Content-Type هو عنوان HTTP يحدد تنسيق البيانات المنقولة بين العميل والخادم. بدون نوع MIME الصحيح، لا يمكن للمتصفح معالجة الاستجابة بشكل صحيح: يظهر الملف النصي ككود خام، ولا تفتح الصورة. وفقًا لـ MDN Web Docs، 2025، Content-Type إلزامي للنقل الصحيح للبيانات من أي نوع في بروتوكول HTTP ويحدد كيف يفسر المستلم نص الرسالة.
النقاط الرئيسية
Content-Type هو عنوان HTTP من مجموعة عناوين التمثيل الذي يخبر المستلم بتنسيق البيانات في نص الرسالة. وهو إلزامي لطلبات واستجابات HTTP التي تحتوي على نص، وبدونه لا يستطيع العميل تفسير البايتات المستلمة بشكل صحيح. بناءً على Content-Type، يختار المتصفح أو التطبيق المحلل المناسب: لـ text/html يشغل محرك HTML، لـ image/png — مفكك تشفير PNG، لـ application/json — محلل JSON.
قيمة Content-Type هي نوع MIME — معرف موحد لتنسيقات البيانات. اختصار MIME يعني Multipurpose Internet Mail Extensions، لأن هذا المعيار تم إنشاؤه أصلاً لمرفقات البريد الإلكتروني. لكنه أصبح أساس HTTP ويستخدم اليوم في كل مكان — من نقل صفحات الويب إلى تبادل البيانات في REST API. يتكون كل نوع MIME من جزئين: فئة رئيسية ونوع فرعي مؤهل، مفصولين بشرطة مائلة.
معامل charset يكمل Content-Type للتنسيقات النصية. على سبيل المثال، Content-Type: text/html; charset=utf-8 يعني أنه يتم نقل مستند HTML بترميز UTF-8. وفقًا لـ IETF RFC 7231، القسم 3.1.1.5، عنوان Content-Type إلزامي لرسائل HTTP التي تحتوي على نص، وغيابه يعامل كـ application/octet-stream أو يؤدي إلى MIME sniffing.
بروتوكول HTTP/0.9، الذي صدر في عام 1991، كان ينقل صفحات HTML فقط، لذلك كان نوع البيانات ضمنيًا افتراضيًا. مع ظهور HTTP/1.0 في RFC 1945، أدرك المطورون الحاجة إلى نقل الصور وأوراق الأنماط والبرامج النصية. قاموا بتكييف معيار MIME من بروتوكول البريد الإلكتروني، وأصبح Content-Type جزءًا لا يتجزأ من HTTP. منذ ذلك الحين، توسع سجل IANA إلى مئات القيم — من text/html المألوف إلى image/avif و application/manifest+json الحديثين.
Content-Type يلعب دورًا حاسمًا في الحماية من الهجمات. إذا أرسل الخادم ملف HTML بنوع MIME text/plain، لن يقوم المتصفح بتنفيذ JavaScript أو بناء DOM — وهذا يمنع هجمات XSS. العنوان X-Content-Type-Options: nosniff، الموصى به من OWASP، يمنع المتصفح تمامًا من تخمين نوع MIME بناءً على المحتوى. وفقًا لـ PortSwigger Research، كانت هجمات MIME sniffing منتشرة بشكل خاص في Internet Explorer 6-9، حيث كان المتصفح يتجاهل Content-Type ويحدد النوع من أول بايتات الملف.
يتم تحديد نوع MIME بتنسيق type/subtype، حيث type هي الفئة العامة للبيانات و subtype هو التنسيق المحدد داخلها. على سبيل المثال، في image/png، الفئة image تشير إلى صورة، والنوع الفرعي png يحدد تنسيق Portable Network Graphics. هناك فقط عدد قليل من الفئات: text، image، audio، video، application، multipart و message. باقي التنوع يأتي من الأنواع الفرعية، التي يوجد منها المئات.
يتم تمرير المعاملات الإضافية عبر فاصلة منقوطة بعد النوع الفرعي. المعامل الأكثر شيوعًا هو charset لتحديد الترميز. Content-Type: application/json; charset=utf-8 يشير إلى أنه يتم نقل مستند JSON بترميز UTF-8. رسميًا، charset لـ application/json زائد لأن JSON دائمًا بتنسيق UTF-8 وفقًا لـ RFC 8259، لكن التحديد الصريح يحسن التوافق مع عملاء HTTP القدامى.
| الفئة | أمثلة الأنواع الفرعية | الوصف |
|---|---|---|
| text | html, plain, css, javascript, csv | تنسيقات نصية قابلة للقراءة البشرية |
| image | jpeg, png, gif, webp, svg+xml, avif | صور نقطية ومتجهة |
| audio | mpeg, ogg, wav, mp4, webm | تنسيقات صوتية للتشغيل المتدفق |
| video | mp4, webm, ogg, x-msvideo, 3gpp | تنسيقات فيديو وحاويات وسائط متعددة |
| application | json, xml, pdf, zip, octet-stream, protobuf | بيانات ثنائية ومنظمة |
| multipart | form-data, mixed, alternative, byteranges | مستندات مركبة من أجزاء متعددة |
أنواع MIME القياسية مسجلة في سجل IANA ولها بادئة فئة رئيسية. الأنواع غير القياسية (خاصة بالبائعين) تستخدم البادئة x- أو تنسيق vnd.company.type — مثلاً application/vnd.google-earth.kml+xml لتنسيق KML من Google. قد لا تتعرف المتصفحات على الأنواع غير القياسية، لذلك للمرفقات غير المعروفة يُستخدم application/octet-stream — تدفق ثنائي عام لا يحاول المتصفح عرضه بل يعرض حفظه كملف.
معامل charset حاسم لعرض النص بشكل صحيح. بدونه، قد يفسر المتصفح الأحرف بشكل غير صحيح، مما يؤدي إلى mojibake. المعيار للويب هو UTF-8، لكن توجد أيضًا ISO-8859-1 (Latin-1) للغات أوروبا الغربية و windows-1251 للسيريلية في المواقع القديمة. توصية W3C هي تحديد charset=utf-8 دائمًا لـ text/html و text/plain، بينما charset غير مطلوب لـ application/json.
عمليًا، يعمل مطورو الويب والتطبيقات المحمولة مع مجموعة محدودة من أنواع MIME. معرفة هذه الأنواع ضرورية لتكوين الخوادم بشكل صحيح وكتابة عملاء HTTP ومعالجة الملفات الثابتة. text/html هو النوع الرئيسي لصفحات الويب، ويتم إرجاعه بواسطة خوادم Apache و Nginx افتراضيًا لملفات HTML. application/xhtml+xml يُستخدم بشكل أقل وفقط لمستندات XHTML.
application/json أصبح المعيار لواجهات REST API. ترجع الخوادم بيانات JSON بنوع MIME هذا، ويرسله العملاء في طلبات POST و PUT. text/javascript (قديم) و application/javascript يُستخدمان لملفات JavaScript. وفقًا لـ استطلاع W3Techs، 2025، JSON هو تنسيق البيانات الأسرع نموًا على الويب، متجاوزًا XML في عام 2018. لخدمات SOAP، لا تزال تُستخدم text/xml أو application/soap+xml.
للصور، يتم تحديد نوع MIME حسب تنسيق الملف: image/jpeg لـ JPEG، image/png لـ PNG، image/gif لـ GIF، image/webp للتنسيق الحديث WebP. image/svg+xml يُستخدم للرسومات المتجهة ويدعم الأنماط والبرامج النصية المضمنة. video/mp4، audio/mpeg و application/pdf هي أنواع أخرى شائعة. لخطوط الويب تُستخدم font/woff2، font/woff و font/ttf.
عند إرسال الملفات عبر نموذج HTML، يُستخدم multipart/form-data — نوع MIME مركب يقسم الطلب إلى أجزاء متعددة. كل جزء له عنوان Content-Type الخاص به و Content-Disposition الذي يحدد اسم الحقل واسم الملف الأصلي. يستقبل الخادم الملف بنوع MIME الفعلي المحدد من قبل المتصفح ويمكنه التحقق منه في جانب الخلفية. application/octet-stream يُستخدم للملفات من نوع غير معروف — لا يحاول المتصفح عرض المحتوى بل يعرض حفظه على القرص.
نوع MIME يؤثر على سياسة التخزين المؤقت لـ CDN والمتصفحات. الصور ذات العناوين المستقرة تُخزن مؤقتًا عادة لفترة طويلة (سنة أو أكثر)، بينما صفحات HTML تُخزن مؤقتًا لدقائق أو ثوانٍ. خوادم CDN مثل Cloudflare و Akamai تستخدم Content-Type لاختيار خوارزمية الضغط: text/* يُضغط بـ gzip أو brotli، image/* لا، لأن الصور مضغوطة بالفعل. التكوين الصحيح لـ Content-Type على الخادم يؤثر مباشرة على أداء تحميل صفحات الويب والتطبيقات المحمولة.
يحدد الخادم عنوان Content-Type في استجابة HTTP بناءً على نوع الملف المطلوب أو المحتوى المُنشأ ديناميكيًا. خوادم الويب الشهيرة مثل Nginx و Apache تحتوي على جداول أنواع MIME مدمجة تربط امتدادات الملفات بـ Content-Type المناسب. مثلاً، index.html يحصل على text/html، و style.css يحصل على text/css. للاستجابات الديناميكية، يحدد المطور Content-Type في كود التطبيق بلغة PHP أو Python أو Java أو Kotlin.
يستخدم العميل Content-Type لاختيار المعالج. إذا أعاد الخادم text/html، يبدأ المتصفح محلل HTML ويبني شجرة DOM. إذا كان image/png — يبدأ مفكك تشفير PNG. إذا كان Content-Type مفقودًا أو غير صحيح، يطبق العميل MIME sniffing — يحاول تخمين النوع من التوقيع (البايتات السحرية) في بداية الملف. JPEG يبدأ بالبايتات FF D8 FF، PNG يبدأ بـ 89 50 4E 47، و PDF يبدأ بـ 25 50 44 46. هذه العملية خطيرة محتملاً ويتم تعطيلها بواسطة العنوان X-Content-Type-Options: nosniff.
في التطبيقات المحمولة، يتم التعامل مع Content-Type بواسطة عملاء HTTP. OkHttp على أندرويد يحلل تلقائيًا عنوان Content-Type من الاستجابة ويوفره عبر طريقة Response.header("Content-Type"). عميل URLSession لنظام iOS يفعل الشيء نفسه عبر خاصية URLResponse.mimeType. في كلتا المنصتين، يُستخدم Content-Type لاختيار المحلل: JSON — عبر Moshi أو Gson على أندرويد، عبر Codable على iOS؛ الصور — عبر Glide أو Coil أو SDWebImage.
التفاوض على المحتوى هو آلية HTTP حيث يحدد العميل تنسيق الاستجابة المطلوب عبر عنوان Accept، ويختار الخادم التنسيق المناسب ويعيده مع Content-Type المقابل. مثلاً، يرسل العميل Accept: application/json، يستجيب الخادم بـ Content-Type: application/json. إذا لم يستطع الخادم توفير التنسيق المطلوب، يعيد 406 Not Acceptable. في REST API، تسمح هذه الآلية لنقطة نهاية واحدة بإرجاع البيانات بتنسيق JSON أو XML أو HTML.
عنوان Content-Type يُستخدم في كل من طلبات HTTP واستجابات HTTP. في الطلبات، يحدد تنسيق نص الطلب، مثلاً عند إرسال JSON عبر POST. في الاستجابات، يحدد تنسيق البيانات المُعادة. الفرق الجوهري هو أن Content-Type للطلب يحدده العميل، بينما Content-Type للاستجابة يحدده الخادم. التحديد غير الصحيح لـ Content-Type في الطلب يؤدي إلى عدم قدرة الخادم على تحليل النص، مع إرجاع خطأ 400 Bad Request أو 415 Unsupported Media Type.
في طلبات HTTP، Content-Type إلزامي لطرق POST و PUT و PATCH إذا كان الطلب يحتوي على نص. GET و HEAD و DELETE عادة لا تستخدم نصًا، لذلك Content-Type غير محدد أو يتم تجاهله لها. عند إرسال نموذج HTML مع السمة enctype="multipart/form-data"، يحدد المتصفح تلقائيًا Content-Type: multipart/form-data مع سلسلة حد فريدة تفصل أجزاء الطلب المركب. كل جزء يُفصل بـ --boundary، ونهاية الطلب تُحدد بـ --boundary--.
في استجابات HTTP، Content-Type يحدده الخادم. إذا لم يحدد الخادم Content-Type، إما أن يفعل العميل MIME sniffing أو يعالج الاستجابة كـ application/octet-stream. طريقة HTTP HEAD تسمح بالحصول على عناوين الاستجابة، بما في ذلك Content-Type، دون نقل النص. هذا مفيد للتحقق من نوع المورد قبل تحميله بالكامل. خوادم CDN قد تعيد تعريف Content-Type عند تحويل المحتوى — مثلاً، عند تحويل الصور إلى WebP.
import okhttp3.*
fun checkContentType() {
val client = OkHttpClient()
val request = Request.Builder()
.url("https://api.example.com/resource")
.head()
.build()
client.newCall(request).execute().use { response ->
val contentType = response.header("Content-Type")
val mediaType = MediaType.parse(contentType)
println("النوع: ${mediaType?.type}, النوع الفرعي: ${mediaType?.subtype}")
}
}
في تطوير التطبيقات المحمولة، يتم التعامل مع عنوان Content-Type تلقائيًا بواسطة عملاء HTTP. في OkHttp على أندرويد، يتم تعيين Content-Type عبر RequestBody: val body = "{}".toRequestBody("application/json".toMediaType()). يدير Retrofit Content-Type عبر التعليقات التوضيحية: @Body لـ JSON، @Part للمتعدد الأجزاء. على iOS، يحدد URLSession Content-Type لـ HTTPBody، ويفعل Alamofire ذلك عبر معامل encoding: JSONEncoding.default أو URLEncoding.default. الإعداد اليدوي لـ Content-Type مطلوب عند العمل مع المقابس الأولية أو البروتوكولات المخصصة.
Content-Type غير الصحيح هو واحد من أكثر المشاكل شيوعًا في تطوير ودمج خدمات الويب. الخطأ الأكثر شيوعًا هو عندما يعيد الخادم text/html بدلاً من application/json. يتلقى العميل JSON كسلسلة HTML، ولا يمكنه تحليلها ويطرح استثناءً. يحدث هذا عندما يكون إطار العمل مهيئًا لـ HTML افتراضيًا وينسى المطور تجاوز Content-Type لنقاط نهاية API. في PHP يظهر هذا عند عدم وجود header('Content-Type: application/json')، في Spring Boot — عند عدم وجود التعليق التوضيحي produces.
ثاني أكثر الأخطاء شيوعًا هو charset غير صحيح أو مفقود. إذا أرسل الخادم text/html; charset=iso-8859-1 والمتصفح يتوقع UTF-8، تظهر الأحرف السيريلية مشوشة (mojibake). هذه المشكلة نموذجية للمواقع القديمة التي لم تنتقل إلى UTF-8. لـ JSON، هذا الخطأ أقل شيوعًا لأن RFC 8259 يفرض UTF-8 دون تفاوض إضافي. الحل هو تحديد charset=utf-8 دائمًا صراحةً لأنواع MIME النصية في تكوين الخادم.
المشكلة الثالثة هي عدم تطابق Content-Type مع المحتوى الفعلي. إذا أرسل الخادم Content-Type: image/png لكن نص الاستجابة يحتوي على صورة WebP، قد لا يفك المتصفح تشفيرها. خوادم CDN أحيانًا تضغط الصور مع تغيير التنسيق لكن دون تحديث عنوان Content-Type. التحقق من تطابق Content-Type مع المحتوى الفعلي هو خطوة إلزامية في اختبار API واختبار التكامل للتطبيقات المحمولة.
لتصحيح الأخطاء، استخدم أدوات المطور في المتصفح (علامة التبويب Network)، أو curl مع العلم -I للتحقق من عناوين الاستجابة، أو محللات حركة المرور مثل Charles Proxy و Wireshark. Nginx يُكون عبر التوجيه include mime.types، Apache — عبر AddType و AddDefaultCharset. للملفات الثابتة، تحقق دائمًا من أن امتداد الملف يطابق نوع MIME الخاص به. للاستجابات الديناميكية في جميع لغات البرمجة، حدد Content-Type صراحةً قبل إخراج البيانات — هذا يمنع الغالبية العظمى من المشاكل.
الأسئلة الشائعة
بدون Content-Type، يقوم المتصفح بتفعيل MIME sniffing — تحليل أول بايتات الاستجابة لتحديد نوع البيانات تلقائيًا. هذا قد يؤدي إلى معالجة غير صحيحة للمحتوى وثغرات أمنية. المتصفحات الحديثة مع العنوان X-Content-Type-Options: nosniff تمنع التخمين تمامًا.
Content-Type يحدد تنسيق البيانات المنقولة في الرسالة الحالية (نص الطلب أو الاستجابة). Accept هو عنوان طلب يخبر الخادم بتنسيق الاستجابة الذي يفضله العميل. Content-Type يحدده مرسل البيانات، بينما Accept يحدده المستلم، وكلاهما يشارك في آلية التفاوض على المحتوى.
نوع MIME الرسمي لـ JSON هو application/json وفقًا لـ RFC 8259. سابقًا كان يُستخدم text/x-json، لكن هذا النوع قديم. معامل charset لـ application/json غير مطلوب لأن JSON دائمًا يُنقل بترميز UTF-8 أو UTF-16 أو UTF-32 مع كشف تلقائي لترتيب البايتات (BOM) وفقًا للمواصفات.
يحدث هذا عندما لا يتجاوز إطار العمل Content-Type الافتراضي لنقاط نهاية API. في PHP يُصلح باستدعاء header('Content-Type: application/json')، في Spring Boot — بالتعليق التوضيحي @GetMapping(produces = "application/json")، في Express.js — بطريقة res.set('Content-Type', 'application/json').
application/octet-stream هو نوع MIME عام للبيانات الثنائية التي تنسيقها غير معروف. لا يحاول المتصفح عرض مثل هذا الملف في النافذة بل يعرض حفظه على القرص. يُستخدم لتنزيلات الملفات ومرفقات البريد الإلكتروني والبيانات المتدفقة عندما لا يستطيع الخادم تحديد النوع الدقيق للمحتوى المنقول.
الخلاصة
سنقوم بتطوير تطبيق جوال جاهز
تقدم IT Sectr تطبيقات iOS وAndroid للشركات الناشئة والشركات منذ عام 2017. سوف نقدم لك النصح ونقترح أفضل حل.
اقرأ أيضًا