نقش Content-Type و تنظیمات خاص jQuery و Ajaxi
درک مفهوم Content-Type در HTTP
پیش از آنکه به سراغ کدها برویم، باید بدانیم Content-Type چیست. این یک هدر (Header) در پروتکل HTTP است که به سرور میگوید: «دادههایی که در بدنه (Body) درخواست برایت فرستادم، از چه نوعی هستند و چگونه باید آنها را تفسیر کنی؟»
اگر سرور بداند دادهها JSON هستند، آنها را پارس میکند؛ اگر بداند فرم هستند، به شکل متغیرهای فرمی با آنها برخورد میکند.
فرمت application/x-www-form-urlencoded
این فرمت، حالت پیشفرض در تمامی فرمهای HTML و همچنین متد $.ajax() در جیکوئری است.
ساختار دادهها:
دادهها در این حالت به صورت جفتهای "کلید=مقدار" که با کاراکتر & از هم جدا شدهاند، ارسال میشوند. فضاهای خالی با + یا کدهای درصد (%20) جایگزین میشوند.
مثال: name=John+Doe&age=25&city=Tehran
چه زمانی از آن استفاده کنیم؟
-
فرمهای ساده ثبتنام یا ورود که فقط شامل متن هستند.
-
زمانی که نیاز به ارسال فایل ندارید.
-
سازگاری کامل با تمامی سرورها و زبانهای سمت سرور (PHP, ASP.NET, Python و ...).
پیادهسازی در jQuery:
$.ajax({
url: '/api/login',
method: 'POST',
data: { username: 'user1', password: '123' },
// contentType به صورت پیشفرض روی application/x-www-form-urlencoded است
success: function(response) {
console.log("ورود موفقیتآمیز");
}
});
فرمت multipart/form-data
زمانی که صحبت از آپلود فایل (عکس، ویدیو، PDF) به میان میآید، فرمت قبلی دیگر کارایی ندارد. در اینجا باید از multipart/form-data استفاده کرد.
ساختار دادهها:
در این حالت، بدنه درخواست به بخشهای مختلفی (Parts) تقسیم میشود که هر بخش با یک "Boundary" (مرز) از دیگری جدا میشود. هر بخش میتواند نوع داده مخصوص به خود را داشته باشد (مثلاً یک بخش متن و بخش دیگر یک فایل باینری).
چالش jQuery با multipart:
به طور معمول، جیکوئری تلاش میکند دادههای شیء (Object) را به رشتههای متنی تبدیل (Serialize) کند. اما فایلهای باینری را نمیتوان سریالسازی کرد. برای حل این مشکل، ما از شیء FormData در جاوااسکریپت استفاده میکنیم.
تنظیم حیاتی: contentType: false
در jQuery، وقتی میخواهید فایل بفرستید، باید دو تنظیم مهم را انجام دهید:
-
contentType: false: این کار به جیکوئری میگوید که هیچ هدری برای Content-Type تنظیم نکند. چرا؟ چون وقتی از FormData استفاده میکنید، خودِ مرورگر باید هدر را به همراه رشتهی منحصربهفرد Boundary بسازد. اگر دستی آن را مقداردهی کنید، سرور نمیتواند مرز بین فایلها را تشخیص دهد.
-
processData: false: این کار مانع از تبدیل دادهها به رشته (Query String) توسط جیکوئری میشود.
var formData = new FormData();
formData.append('profile_pic', $('#fileInput')[0].files[0]);
formData.append('username', 'ali');
$.ajax({
url: '/api/upload',
method: 'POST',
data: formData,
contentType: false, // بسیار مهم
processData: false, // بسیار مهم
success: function(res) {
alert("فایل آپلود شد!");
}
});
فرمت application/json
با ظهور APIهای مدرن و فریمورکهایی مثل React و Angular، فرمت JSON به استاندارد طلایی تبادل داده تبدیل شد. برخلاف فرمتهای قبلی، JSON اجازه میدهد ساختارهای پیچیده و تودرتو (Nested Objects) را به راحتی ارسال کنید.
تفاوت در ارسال:
-
در جیکوئری، برخلاف حالت فرمی، دادهها به صورت خودکار به JSON تبدیل نمیشوند. شما باید خودتان شیء را به رشته تبدیل کنید.
پیادهسازی در jQuery:
$.ajax({
url: '/api/update-profile',
method: 'POST',
contentType: 'application/json', // به سرور میگوید داده JSON است
data: JSON.stringify({
id: 1,
skills: ['JS', 'jQuery', 'CSS'],
address: { city: 'Tehran', zip: '12345' }
}),
success: function(res) {
console.log("پروفایل بروزرسانی شد");
}
});
مقایسه در یک نگاه (Table)
|
ویژگی |
application/x-www-form-urlencoded |
multipart/form-data |
application/json |
|
کاربرد اصلی |
فرمهای متنی ساده |
آپلود فایل و دادههای ترکیبی |
APIهای مدرن و دادههای پیچیده |
|
پیشفرض jQuery |
بله |
خیر |
خیر |
|
پشتیبانی از فایل |
خیر |
بله (عالی) |
محدود (فقط Base64) |
|
ساختار داده |
Key=Value |
Multipart with Boundary |
JSON Object |
|
تنظیم خاص |
نیاز ندارد |
contentType: false |
JSON.stringify() |
بررسی اشتباهات رایج
اشتباه ۱: فراموش کردن processData: false هنگام ارسال فایل
-
اگر این را فراموش کنید، جیکوئری سعی میکند شیء حجیم File یا FormData را به یک رشته متنی تبدیل کند که منجر به خطای "Illegal invocation" یا مصرف وحشتناک رم مرورگر میشود.
اشتباه ۲: تنظیم دستی هدر Multipart
-
برخی تصور میکنند باید بنویسند contentType: 'multipart/form-data'. این کار باعث میشود هدر ارسالی فاقد پارامتر boundary باشد و سرور عملاً هیچ دادهای را دریافت نکند. همیشه برای فایلها از false استفاده کنید.
اشتباه ۳: ارسال JSON بدون JSON.stringify
-
اگر contentType را روی application/json بگذارید اما داده را به صورت یک شیء جاوااسکریپتی مستقیم به data پاس دهید، جیکوئری آن را به فرمت key=value تبدیل میکند و سرور که منتظر {} است، با خطای Parse مواجه میشود.
چه زمانی از کدام استفاده کنیم؟ (نتیجهگیری)
-
اگر فقط متن میفرستید (مثلاً جستجو یا لاگین ساده): از همان حالت پیشفرض (urlencoded) استفاده کنید. نیاز به تنظیم contentType ندارید.
-
اگر قصد آپلود عکس، ویدیو یا هر فایلی را دارید: حتماً از FormData استفاده کنید و تنظیمات contentType: false و processData: false را اعمال کنید.
-
اگر با یک REST API کار میکنید که انتظار ساختار درختی دارد: از application/json استفاده کنید و یادتان باشد داده را با JSON.stringify() ارسال کنید.
درک این تفاوتهای ظریف در متد $.ajax() نه تنها از باگهای احتمالی جلوگیری میکند، بلکه باعث میشود اپلیکیشن شما تعامل استانداردتر و بهینهتری با سمت سرور داشته باشد.
0 نظر
هنوز نظری برای این مقاله ثبت نشده است.