یکی از سوالات رایجی که زیاد پرسیده میشود این است که چطور باید یک تصویر را به همراه فیلدهای دیگر به سمت سرور ارسال کرد. اکثر مثالهای آپلود عکس بدین صورت هستند که از یک کتابخانه پویا استفاده میکنند که همان لحظه عکس را به سمت سرور ارسال میکنند. ولی یک مثال و کاربرد بسیار ساده این است که من میخواهم اطلاعات فرم و عکس Input File را به همراه یکدیگر همزمان ارسال نمایم که اتفاقا این مسئله به شدت هم اتفاق میافتد. برای مثال شما اطلاعات یک دانش آموز را وارد سیستم میکنید که به صورت ایجکسی به سمت سرور ارسال میشوند و حالا نیاز است که تصویر دانش آموز هم وارد سیستم شود که ارسال این تصویر نیز از طریق یک input File رخ میدهد. نحوه کار با یک input File در سمت سرور در سایت جاری پرداخته شده است که برای پرهیز از تکرار از آن خودداری میکنم.
XMLHttpRequest رابطی است که به شما امکان نقل و انتقالات را از سمت کاربر، به سمت سرور و سپس دریافت پاسخ آن را میدهد. این رابط طوری طراحی شدهاست که دیگر برای این جابجایی نیازی به بارگزاری مجدد کل صفحه نباشد و قسمتی از اطلاعات صفحات به روز شوند، مزاحمتی برای کاربر ایجاد نشود. به همین دلیل از این رابط، در پشت صحنههای عملیات ایجکسی استفاده زیادی میشود. در این مقاله با استفاده از خصوصیتی به نام request.IsAjax بررسی میشود که آیا درخواست رسیده به سرور از نوع ایجکسی است یا خیر. اگر به سورس نوشته شده این متد نگاه دقیقتری بیندازیم، متوجه میشویم کاری که این متد انجام میدهد، در واقع در یک خط خلاصه میشود و آن بررسی هدری برای وجود درخواست از نوع XMLHttpRequest است:
برای اطلاعات بیشتر در مورد این رابط، خصوصیتها، متدهایش و پشتیبانی سایر مرورگرها از این خواص، بهتر است به صفحه مستندات موزیلا نگاهی بیندازید.
یکی از متدهای این رابط، متد ارسال آن (send) میباشد که میتواند رابطی به نام formData را انتقال دهد و این رابط از نوع مجموعهای از کلید و مقدارهاست. این رابط زمانی به کار گرفته میشود که انکدینگ فرم خود را بر روی multipart/form-data قرار داده باشید. این ساختار میتواند توسط دستور for of بررسی گردد. برای آشنایی بیشتر با متدهای آن این صفحه را مطالعه فرمایید.
هنگام ارسال فایل در حالت postback، ما فرم را بر روی multipart قرار میدهیم تا امکان ارسال آن توسط formData مهیا شود. ولی از آنجاکه ما از ایجکس استفاده میکنیم، بهتر است که خودمان مستقیما از این ساختار استفاده کنیم.
بخشی از فرم Html
برای زیباسازی کار، برای المان input File در بالا، از کتابخانه Bootstrap FileStyle استفاده شدهاست.
سپس کد جی کوئری زیر را مینویسیم:
در کد بالا ابتدا یک شیء FormData ایجاد میشود و سپس کلیدو مقدارهایی نیز به آن انتساب داده میشوند. در صورتیکه Input File شما، امکان آپلود چندین فایل همزمان را میدهد، میتوانید با استفاده از حلقهی مورد نظر، یکی یکی آنها را به این شیء اضافه کنید و به ترتیب اسامی pictue-0 ,picture-1 و ... به آنها انتساب داده میشود. در نهایت تنها کاری که لازم است انجام دهید این است که روال همیشگی را طی کنید و این شیء را به عنوان data، در اختیار متد ajax قرار دهید تا ارسال شود.
توجه به این نکته ضروری است و با توجه کدهایی که در نت دیدم و بسیاری از آن حتی به عنوان پاسخ صحیح در نظر گرفته شده بودند این است که شیء FormData شامل هیچ سازندهای نیست و باید با استفاده از متد append آنها را اضافه کنید.
XMLHttpRequest رابطی است که به شما امکان نقل و انتقالات را از سمت کاربر، به سمت سرور و سپس دریافت پاسخ آن را میدهد. این رابط طوری طراحی شدهاست که دیگر برای این جابجایی نیازی به بارگزاری مجدد کل صفحه نباشد و قسمتی از اطلاعات صفحات به روز شوند، مزاحمتی برای کاربر ایجاد نشود. به همین دلیل از این رابط، در پشت صحنههای عملیات ایجکسی استفاده زیادی میشود. در این مقاله با استفاده از خصوصیتی به نام request.IsAjax بررسی میشود که آیا درخواست رسیده به سرور از نوع ایجکسی است یا خیر. اگر به سورس نوشته شده این متد نگاه دقیقتری بیندازیم، متوجه میشویم کاری که این متد انجام میدهد، در واقع در یک خط خلاصه میشود و آن بررسی هدری برای وجود درخواست از نوع XMLHttpRequest است:
return request.Headers["X-Requested-With"] == "XMLHttpRequest";
یکی از متدهای این رابط، متد ارسال آن (send) میباشد که میتواند رابطی به نام formData را انتقال دهد و این رابط از نوع مجموعهای از کلید و مقدارهاست. این رابط زمانی به کار گرفته میشود که انکدینگ فرم خود را بر روی multipart/form-data قرار داده باشید. این ساختار میتواند توسط دستور for of بررسی گردد. برای آشنایی بیشتر با متدهای آن این صفحه را مطالعه فرمایید.
هنگام ارسال فایل در حالت postback، ما فرم را بر روی multipart قرار میدهیم تا امکان ارسال آن توسط formData مهیا شود. ولی از آنجاکه ما از ایجکس استفاده میکنیم، بهتر است که خودمان مستقیما از این ساختار استفاده کنیم.
بخشی از فرم Html
<div> <label>تصویر</label> <div> <input id="picture" type="file" data-buttonText="انتخاب تصویر"> </div> </div> <div> <label>کد ملی</label> <div> <input id="txtNationalCode" required="" maxlength="10" type="text"> </div> </div> <div> <label>نام</label> <div> <input id="txtName" type="text" maxlength="50" required=""> </div> </div> <div class="form-group"> <div class="col-sm-4 col-sm-offset-2"> <button class="btn btn-primary" id="btnSubmit" type="submit">ذخیره</button> <button class="btn btn-white" id="btnClear" type="submit">لغو</button> </div> </div>
سپس کد جی کوئری زیر را مینویسیم:
var formData = new FormData(); formData.append('FirstName', $("#txtName").val()); formData.append('NationalCode', $("#txtNationalCode").val()); jQuery.each($('#picture')[0].files, function (i, file) { formData.append('picture-'+i, file); }); $.ajax({ type: "POST", dataType: "json", url: address, data: formData, success: function (data) { //..... }, error: function (data) { //...... } });
توجه به این نکته ضروری است و با توجه کدهایی که در نت دیدم و بسیاری از آن حتی به عنوان پاسخ صحیح در نظر گرفته شده بودند این است که شیء FormData شامل هیچ سازندهای نیست و باید با استفاده از متد append آنها را اضافه کنید.