انتقل إلى محتوى الدرس
فقرة فرعية #6 من درس: رسائل HTTP

HTTP Message Headers vs Body رؤوس الرسالة مقابل جسم الرسالة

تعرّف في هذا الدرس على رسائل HTTP (HTTP Messages) ونوعَيها: الطلب والاستجابة، وتشريح أقسامها الأربعة من سطر البداية والرؤوس والسطر الفارغ وجسم الرسالة، وكيفية فحصها عملياً وتشخيص أخطائها في تطوير الويب وأمن المعلومات.
10 صفوف تعليمية
تكنولوجيا الويب
1,212 مشاهدة

شرح صفوف ومحتوى الفقرة

الصف 1 شرح توضيحي

لفهم الفرق بين رؤوس الرسالة (Headers) وجسم الرسالة (Body) بسهولة، تذكّر دائماً مثال الطرد البريدي: الملصق الخارجي المكتوب عليه عنوان المستلم ووزن الصندوق ونوع البضاعة بالداخل هو رؤوس الرسالة، أما البضاعة نفسها الموجودة داخل الصندوق فهي جسم الرسالة:

  • الوظيفة: الرؤوس تحمل معلومات وصفية وتعليمات تحكم تساعد المتصفح والسيرفر على فهم الرسالة والتعامل معها، بينما يحمل الجسم المحتوى الفعلي الذي نريد إرساله أو عرضه (مثل صفحة الموقع، أو صورة، أو بيانات نموذج).
  • الشكل وطريقة الكتابة: تُكتب الرؤوس دائماً كأسطر نصية منظمة بصيغة الاسم: القيمة، أما الجسم فيمكن أن يكون نصاً عادياً أو كود HTML أو بيانات JSON أو حتى ملف صورة أو فيديو.
  • المكان والإلزامية: تأتي الرؤوس دائماً قبل السطر الفارغ ولا تخلو منها أي رسالة عملية (لأن رأس Host الذي يحدد اسم الموقع إلزامي في كل طلب HTTP/1.1)، بينما يأتي الجسم دائماً بعد السطر الفارغ وهو اختياري قد لا نحتاجه في كثير من الرسائل.

وعندما تحتوي الرسالة على جسم، نضع في الرؤوس معلومتين أساسيتين لمساعدة الطرف المستقبل على قراءة الجسم بشكل صحيح: رأس Content-Type ليخبره ما نوع هذا المحتوى؟ (مثل application/json أو text/html)، ورأس Content-Length ليخبره كم عدد بايتات هذا المحتوى؟ كما في المثال الآتي:

الصف 2 كود برمجي
نص
POST /api/progress HTTP/1.1
Host: closetag.com
Content-Type: application/json
Content-Length: 31

{"course": "HTTP", "lesson": 3}
الصف 3 شرح توضيحي

تفصيل تقني متقدم: متى يُمنع وجود جسم الرسالة؟ وتصحيح المفاهيم الشائعة (RFC 9110 & RFC 9112)

يضع المعياران RFC 9112 (القسم 6) و RFC 9110 (الأقسام 8.6 و 9.3 و 15.3) قواعد دقيقة تفصل بين أحكام وجود الجسم في الطلبات مقابل الاستجابات:

  • قاعدة وجود الجسم في الطلبات (Requests): نحوياً وفق RFC 9112، يدل وجود رأس Content-Length أو Transfer-Encoding في الطلب على وجود جسم رسالة. أما دلالياً وفق RFC 9110 (القسم 9.3)، فإن إرسال جسم داخل طلبات GET و HEAD و DELETE ليس له معنى دلالي معرَّف (No Defined Semantics)، ويوصي المعيار العميل بعدم إرسال جسم معها (SHOULD NOT) لأن الخوادم والوسطاء قد تتجاهله أو ترفض الطلب؛ ولذلك تُرسل هذه الطلبات عملياً دون جسم وتنتهي فور السطر الفارغ CRLF.
  • استجابات HEAD و 304 Not Modified (رأس طول بلا جسم فعلي): ينص المعيار RFC 9112 على أن أي استجابة لطلب HEAD وأي استجابة تحمل الرمز 304 Not Modified يُحظر قطعياً أن تحتوي على جسم رسالة بعد السطر الفارغ، حتى لو وُجد رأس Content-Length داخل الرأس! فوفق المعيار RFC 9110 (القسم 8.6)، يحق للخادم إرسال Content-Length في استجابة HEAD أو 304 لإخبار العميل بحجم المورد لو طُلب بفعل GET، لكن محلل الشبكة ينهي قراءة الرسالة فوراً عند السطر الفارغ CRLF بصفر بايت في الجسم.
  • ردود 1xx الإعلامية واستجابات 204 No Content و 205 Reset Content: تخلو هذه الاستجابات من جسم الرسالة دائماً؛ فيُحظر معيارياً في ردود 1xx و 204 No Content وجود أي جسم أو إرسال رأس Content-Length أو Transfer-Encoding، كما يحظر المعيار RFC 9110 (القسم 15.3.6) على الخادم توليد أي جسم في استجابة 205 Reset Content (وتُرسل بطول صفري Content-Length: 0).

يوضّح المثال الآتي هذا السلوك المعياري بدقة؛ إذ يرسل العميل طلب HEAD لفحص حجم ملف دون تحميله، فيرد الخادم برأس Content-Length بقيمة 4520 وتنتهي الرسالة فوراً بعد السطر الفارغ دون أي بايت في الجسم:

الصف 4 كود برمجي
نص
# === [1] Client sends HEAD to inspect resource metadata only ===
HEAD /manuals/http-rfc-guide.pdf HTTP/1.1
Host: docs.closetag.com
Accept: application/pdf
الصف 5 كود برمجي
نص
# === [2] Server responds with GET metadata & 0 body bytes ===
HTTP/1.1 200 OK
Date: Mon, 02 Nov 2026 12:35:00 GMT
Content-Type: application/pdf
Content-Length: 4520
ETag: "pdf-v2-4520"
الصف 6 شرح توضيحي

تفصيل تقني متقدم: النقل المجزأ (Chunked) والرؤوس اللاحقة (Trailers) وحمولات Multipart وقاعدة تعارض التأطير (RFC 9112 §7.1 & RFC 9110 §6.5)

عندما يبث الخادم محتوى ديناميكياً لا يُعرف حجمه الإجمالي مسبقاً، فإنه يستغني عن رأس Content-Length ويرسل بدلاً منها رأس Transfer-Encoding بقيمة chunked؛ حيث يُرسل كل جزء مسبوقاً بحجمه بالنظام الست عشري على سطر ينتهي بـ CRLF، ويُختتم البث بسطر طوله 0.

الرؤوس اللاحقة بعد الجسم (HTTP Trailer Fields — RFC 9110 §6.5 و RFC 9112 §7.1.2): يتيح النقل المجزأ chunked (وكذلك إطار HEADERS الختامي بعد DATA في HTTP/2 و HTTP/3) إرسال حقول رؤوس بعد انتهاء جسم الرسالة تُسمى Trailers؛ وتُستخدم لإرسال بيانات وصفية لا تتوافر قيمتها إلا بعد الانتهاء من توليد الجسم بالكامل، مثل زمن المعالجة الفعلي Server-Timing أو البصمة الرقمية للتحقق من سلامة البيانات Content-Digest، وذلك بعد الإعلان عن اسمه مسبقاً في رأس Trailer داخل الرأس.

القاعدة المعيارية لتعارض Transfer-Encoding و Content-Length (RFC 9112): يحظر المعيار على المرسِل الجمع بين الرأسين في رسالة واحدة. وإذا استُلمت رسالة تجمعهما معاً، فإن Transfer-Encoding تجبُّ Content-Length؛ ونظراً لكون هذا التعارض مؤشراً على هجمات تهريب طلبات HTTP (HTTP Request Smuggling)، يوصي المعيار المستقبِل برفض الرسالة كخطأ (400 Bad Request) أو إغلاق الاتصال، وإذا اختار الخادم الوسيط تمرير الرسالة فيجب عليه إلزاماً (MUST) حذف رأس Content-Length وإزالتها تماماً قبل تمرير الرسالة.

أما عند رفع الملفات مع حقول نصية في طلب واحد، فيُستخدم النوع المتعدد الأجزاء multipart/form-data مع فاصل نصي فريد boundary يقسم جسم الرسالة من الداخل كما في الأمثلة الثلاثة الآتية:

الصف 7 كود برمجي
نص
# A) Chunked Response + Trailer Field After Body (RFC 9112 §7.1.2)
HTTP/1.1 200 OK
Content-Type: text/plain; charset=UTF-8
Transfer-Encoding: chunked
Trailer: Server-Timing

8
CloseTag
0
Server-Timing: render;dur=18.4
الصف 8 كود برمجي
نص
# B) Multipart Request Body (Form field + uploaded file)
POST /upload HTTP/1.1
Host: www.closetag.com
Content-Type: multipart/form-data; boundary=CTBoundary99

--CTBoundary99
Content-Disposition: form-data; name="course"

HTTP
--CTBoundary99--
الصف 9 صورة توضيحية
رسم توضيحي يقارن بين رؤوس الرسالة للبيانات الوصفية والتحكم وجسم الرسالة للحمولة الفعلية للبيانات عبر الفاصل الوسطي CRLF من حيث الغرض الأساسي والصيغة القياسية والموقع والحضور
الصف 10 ملاحظة هامة