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

HTTP Message Structure بنية رسالة HTTP القياسية

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

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

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

تشبه أي رسالة HTTP طرداً بريدياً منظماً يتكون من أربعة أقسام مرتبة بالترتيب نفسه دائماً (سواء كانت رسالة طلب أو رسالة استجابة):

  1. سطر البداية (Start-Line — إلزامي): هو أول سطر في أعلى الرسالة، ويحدد نوع الرسالة وهدفها باختصار.
  2. رؤوس الرسالة (Headers — صفر أو أكثر): تشبه البطاقة الملصقة على الطرد من الخارج؛ وهي أسطر تحمل معلومات إضافية عن الرسالة (مثل اسم الموقع ونوع المحتوى وحجمه).
  3. السطر الفارغ الفاصل (Blank Line — إلزامي): سطر فارغ تماماً يفصل بين البطاقة الخارجية (الرؤوس) وبين البضاعة الموجودة داخل الطرد.
  4. جسم الرسالة (Message Body — اختياري): هو المحتوى الفعلي داخل الطرد (مثل كود الصفحة أو بيانات المستخدم)، ويأتي دائماً بعد السطر الفارغ، وقد يكون فارغاً إذا لم نكن بحاجة لإرسال محتوى.

يُطلق على القسمين الأول والثاني معاً (سطر البداية + رؤوس الرسالة) اسم مقدمة/رأس الرسالة (Message Head)، بينما يمثل القسم الرابع جسم الرسالة (Message Body) كما يظهر في القالب التوضيحي الآتي:

الصف 2 كود برمجي
نص
# RFC 9112 Generic HTTP Message Syntax (ABNF)
HTTP-message = start-line CRLF
               *( field-line CRLF )
               CRLF
               [ message-body ]
الصف 3 شرح توضيحي

لاحظ كيف يُكتب كل قسم من الأقسام الأربعة في الواقع العملي:

  • في سطر البداية: نكتب في الطلب (الفعل + المسار + الإصدار)، ونكتب في الاستجابة (الإصدار + رقم الحالة + كلمة التوضيح).
  • في رؤوس الرسالة: نكتب كل رأس في سطر مستقل بصيغة الاسم: القيمة (مثل Host لاسم الموقع، وContent-Type لنوع المحتوى، وContent-Length لطول الجسم بالبايتات). ولا يهم إن كتبت اسم الرأس بحروف كبيرة أو صغيرة.
  • في السطر الفارغ وجسم الرسالة: نترك سطراً فارغاً تماماً (CRLF)، ثم نضع محتوى الجسم إن وُجد.

قارن في المثالين الآتيين بين طلب بسيط لجلب صفحة (بدون جسم)، وطلب إرسال بيانات يحتوي على جسم طوله 25 بايت بالضبط:

الصف 4 كود برمجي
نص
# A) GET Request (Start-Line + Headers + Blank Line, No Body)
GET /index.html HTTP/1.1
Host: www.closetag.com
Accept: text/html
الصف 5 كود برمجي
نص
# B) POST Request (All 4 Sections Including JSON Message Body)
POST /api/users HTTP/1.1
Host: www.closetag.com
Content-Type: application/json
Content-Length: 25

{"username": "ahmed_ali"}
الصف 6 شرح توضيحي

وبالمثل، تنطبق الأقسام الأربعة القياسية ذاتها بالترتيب نفسه على رسالة الاستجابة العائدة من الخادم إلى العميل. إذ يتصدر سطر الحالة مطلع الرسالة، تليه حقول رؤوس الاستجابة مثل Content-Type و Content-Length، ثم السطر الفارغ الفاصل CRLF. ويأتي أخيراً جسم الاستجابة الحامل لمستند HTML كما يظهر في المثال والمخطط التشريحي أدناه:

الصف 7 كود برمجي
نص
# HTTP Response (Start-Line + Headers + Blank Line + 137-Byte Body)
HTTP/1.1 200 OK
Content-Type: text/html; charset=UTF-8
Content-Length: 137

<!DOCTYPE html>
<html>
  <head><title>CloseTag</title></head>
  <body>
    <h1>Welcome to CloseTag</h1>
    <p>HTTP</p>
  </body>
</html>
الصف 8 صورة توضيحية
مخطط تشريحي يقارن الأقسام الأربعة القياسية لرسالة HTTP (سطر البداية، حقول الرؤوس، السطر الفارغ الفاصل CRLF، وجسم الرسالة الاختياري) بين رسالة الطلب ورسالة الاستجابة
الصف 9 شرح توضيحي

مثال كامل متصل: طلب HTTP حقيقي والاستجابة المقابلة له سطراً بسطر

لمعاينة كيف تترابط الأقسام الأربعة في دورة اتصال حقيقية كاملة، تأمل السيناريو المتصل الآتي: يرسل العميل طلب إنشاء طلبية جديدة يحمل جسماً بصيغة JSON طوله 30 بايت بالضبط، فيعالجه الخادم ويعيد استجابة مقابلة برمز الإنشاء 201 Created تحمل جسماً طوله 40 بايت:

الصف 10 كود برمجي
نص
# === [1] OUTBOUND HTTP REQUEST (Client -> Server) ===
POST /api/v1/orders HTTP/1.1
Host: store.closetag.com
User-Agent: CloseTagClient/2.0
Content-Type: application/json
Accept: application/json
Content-Length: 30

{"item": "Keyboard", "qty": 1}
الصف 11 كود برمجي
نص
# === [2] MATCHING HTTP RESPONSE (Server -> Client) ===
HTTP/1.1 201 Created
Date: Mon, 02 Nov 2026 12:30:00 GMT
Server: nginx
Location: /api/v1/orders/904
Content-Type: application/json
Content-Length: 40

{"order_id": 904, "status": "confirmed"}
الصف 12 شرح توضيحي

يُفصّل الجدول التشريحي الآتي وظيفة كل سطر في هذه الدورة المتصلة وكيف استجابت رؤوس الخادم لمعطيات الطلب:

الرسالة والقسم السطر المقابل في الكود الوظيفة التشريحية وعلاقة الطلب بالاستجابة
الطلب — سطر البداية السطر الأول (الفعل POST ومسار الواجهة) يحدد فعل الإنشاء POST، ومسار الواجهة بصيغة الأصل origin-form، وإصدار البروتوكول HTTP/1.1.
الطلب — رأس المضيف رأس Host للنطاق المستهدف رأس إلزامي في HTTP/1.1 تحدد النطاق المستهدف store.closetag.com على الخادم.
الطلب — التفاوض على المحتوى رأسا Content-Type و Accept تُخبر الخادم أن جسم الطلب المرسل هو application/json، وتطلب منه أن يعيد الرد بالصيغة نفسها.
الطلب — رأس طول الجسم رأس Content-Length بقيمة 30 تُلزم محلل الخادم بقراءة 30 بايت بالضبط فور انتهاء السطر الفارغ.
الطلب — السطر الفارغ والجسم الفاصل CRLF ثم كائن JSON يفصل السطر الفارغ الرأس عن الجسم، وتنتقل البايتات الثلاثون إلى تطبيق الخادم لإنشاء الطلبية.
الاستجابة — سطر الحالة سطر الحالة برمز 201 Created يرد الخادم برمز 201 Created تأكيداً لنجاح فعل POST وإنشاء مورد جديد فعلياً.
الاستجابة — رأس الموقع رأس Location لمعرّف الطلبية 904 تقترن برمز 201 لتزويد العميل بالمسار الدقيق للطلبية الجديدة التي أُنشئت برقم 904.
الاستجابة — رؤوس المحتوى رأس Content-Type ورأس الطول بقيمة 40 يلبي الخادم طلب العميل في Accept فيعيد النتيجة بصيغة application/json ويعلن أن حجمها 40 بايت.
الاستجابة — السطر الفارغ والجسم الفاصل CRLF ثم كائن التأكيد بعد السطر الفارغ الفاصل، يرسل الخادم كائن التأكيد المكون من 40 بايت ليقرأه العميل ويغلق الدورة بنجاح.
الصف 13 شرح توضيحي

مختبر تفاعلي: ابنِ رسالة HTTP واضغط على أي سطر فيها لمعرفة وظيفته التشريحية

استخدم الأداة التفاعلية أدناه لتجربة تغيير فعل الطلب والمسار والرؤوس وكتابة نصوص عربية أو إنجليزية داخل جسم الرسالة، وانقر على أي سطر في المعاينة اليسرى ليظهر لك شرح وظيفته الدقيقة. ولاحظ كيف يظهر محرفا \r\n في نهاية كل سطر في HTTP/1.1، وكيف يُحسب طول Content-Length بالبايت تلقائياً بترميز UTF-8، وكيف يعرض المختبر محاكاة منطقية مبسّطة لتحول أقسام الرسالة إلى إطاري HEADERS و DATA في HTTP/2 و HTTP/3 (علماً أن الإطارات الفعلية على السلك تكون ثنائية ومضغوطة):

الصف 14 معاينة حية
الصف 15 شرح توضيحي

تفصيل تقني متقدم: أشكال هدف الطلب الأربعة (Request-Target Forms) من البسيط إلى المتقدم (RFC 9112 §3.2)

في الأمثلة السابقة رأينا الشكل القياسي اليومي لهدف الطلب داخل سطر البداية. ولتغطية جميع حالات الاتصال المباشر أو عبر الوسطاء، يحدّد المعيار RFC 9112 (القسم 3.2) أربعة أشكال قياسية لهدف الطلب (request-target):

  • صيغة المسار الأصلي (origin-form): المسار النسبي متبوعاً باستعلام اختياري؛ وهي الصيغة القياسية الأكثر شيوعاً عند مخاطبة الخادم الأصلي مباشرةً مع رأس Host.
  • الصيغة المطلقة الكاملة (absolute-form): عنوان المورد الكامل شاملاً المخطط والمضيف؛ وتُستخدم في HTTP/1.1 عند إرسال الطلب عبر خادم وسيط أمامي (Forward Proxy).
  • صيغة السلطة (authority-form): اسم المضيف ورقم المنفذ فقط؛ وتُستخدم حصراً مع الفعل CONNECT لطلب إنشاء نفق اتصال مباشر (TCP Tunnel) عبر الخادم الوسيط (لا يشفّر CONNECT البيانات بذاته، لكنه يُستخدم غالباً لتمرير اتصالات TLS / HTTPS المشفرة عبر ذلك النفق).
  • صيغة النجمة العامة (asterisk-form): رمز النجمة المفردة *؛ وتُستخدم مع الفعل OPTIONS للاستعلام عن قدرات الخادم ككل بدلاً من مورد محدد.
الصف 16 كود برمجي
نص
# 1. origin-form (Standard request to an origin server)
GET /tutorials/http?page=1 HTTP/1.1
Host: www.closetag.com

# 2. absolute-form (Request sent via a forward proxy)
GET http://www.closetag.com/tutorials/http HTTP/1.1
Host: www.closetag.com
الصف 17 كود برمجي
نص
# 3. authority-form (Used only with CONNECT to open a TCP tunnel)
CONNECT www.closetag.com:443 HTTP/1.1
Host: www.closetag.com:443

# 4. asterisk-form (Server-wide OPTIONS capability check)
OPTIONS * HTTP/1.1
Host: www.closetag.com
الصف 18 ملاحظة هامة