شرح صفوف ومحتوى الفقرة
تشبه أي رسالة HTTP طرداً بريدياً منظماً يتكون من أربعة أقسام مرتبة بالترتيب نفسه دائماً (سواء كانت رسالة طلب أو رسالة استجابة):
- سطر البداية (Start-Line — إلزامي): هو أول سطر في أعلى الرسالة، ويحدد نوع الرسالة وهدفها باختصار.
- رؤوس الرسالة (Headers — صفر أو أكثر): تشبه البطاقة الملصقة على الطرد من الخارج؛ وهي أسطر تحمل معلومات إضافية عن الرسالة (مثل اسم الموقع ونوع المحتوى وحجمه).
- السطر الفارغ الفاصل (Blank Line — إلزامي): سطر فارغ تماماً يفصل بين البطاقة الخارجية (الرؤوس) وبين البضاعة الموجودة داخل الطرد.
- جسم الرسالة (Message Body — اختياري): هو المحتوى الفعلي داخل الطرد (مثل كود الصفحة أو بيانات المستخدم)، ويأتي دائماً بعد السطر الفارغ، وقد يكون فارغاً إذا لم نكن بحاجة لإرسال محتوى.
يُطلق على القسمين الأول والثاني معاً (سطر البداية + رؤوس الرسالة) اسم مقدمة/رأس الرسالة (Message Head)، بينما يمثل القسم الرابع جسم الرسالة (Message Body) كما يظهر في القالب التوضيحي الآتي:
# RFC 9112 Generic HTTP Message Syntax (ABNF)
HTTP-message = start-line CRLF
*( field-line CRLF )
CRLF
[ message-body ]
لاحظ كيف يُكتب كل قسم من الأقسام الأربعة في الواقع العملي:
- في سطر البداية: نكتب في الطلب (الفعل + المسار + الإصدار)، ونكتب في الاستجابة (الإصدار + رقم الحالة + كلمة التوضيح).
- في رؤوس الرسالة: نكتب كل رأس في سطر مستقل بصيغة
الاسم: القيمة(مثلHostلاسم الموقع، وContent-Typeلنوع المحتوى، وContent-Lengthلطول الجسم بالبايتات). ولا يهم إن كتبت اسم الرأس بحروف كبيرة أو صغيرة. - في السطر الفارغ وجسم الرسالة: نترك سطراً فارغاً تماماً (
CRLF)، ثم نضع محتوى الجسم إن وُجد.
قارن في المثالين الآتيين بين طلب بسيط لجلب صفحة (بدون جسم)، وطلب إرسال بيانات يحتوي على جسم طوله 25 بايت بالضبط:
# A) GET Request (Start-Line + Headers + Blank Line, No Body)
GET /index.html HTTP/1.1
Host: www.closetag.com
Accept: text/html
# 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"}
وبالمثل، تنطبق الأقسام الأربعة القياسية ذاتها بالترتيب نفسه على رسالة الاستجابة العائدة من الخادم إلى العميل. إذ يتصدر سطر الحالة مطلع الرسالة، تليه حقول رؤوس الاستجابة مثل Content-Type و Content-Length، ثم السطر الفارغ الفاصل CRLF. ويأتي أخيراً جسم الاستجابة الحامل لمستند HTML كما يظهر في المثال والمخطط التشريحي أدناه:
# 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>
مثال كامل متصل: طلب HTTP حقيقي والاستجابة المقابلة له سطراً بسطر
لمعاينة كيف تترابط الأقسام الأربعة في دورة اتصال حقيقية كاملة، تأمل السيناريو المتصل الآتي: يرسل العميل طلب إنشاء طلبية جديدة يحمل جسماً بصيغة JSON طوله 30 بايت بالضبط، فيعالجه الخادم ويعيد استجابة مقابلة برمز الإنشاء 201 Created تحمل جسماً طوله 40 بايت:
# === [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}
# === [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"}
يُفصّل الجدول التشريحي الآتي وظيفة كل سطر في هذه الدورة المتصلة وكيف استجابت رؤوس الخادم لمعطيات الطلب:
| الرسالة والقسم | السطر المقابل في الكود | الوظيفة التشريحية وعلاقة الطلب بالاستجابة |
|---|---|---|
| الطلب — سطر البداية | السطر الأول (الفعل 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 بايت ليقرأه العميل ويغلق الدورة بنجاح. |
مختبر تفاعلي: ابنِ رسالة HTTP واضغط على أي سطر فيها لمعرفة وظيفته التشريحية
استخدم الأداة التفاعلية أدناه لتجربة تغيير فعل الطلب والمسار والرؤوس وكتابة نصوص عربية أو إنجليزية داخل جسم الرسالة، وانقر على أي سطر في المعاينة اليسرى ليظهر لك شرح وظيفته الدقيقة. ولاحظ كيف يظهر محرفا \r\n في نهاية كل سطر في HTTP/1.1، وكيف يُحسب طول Content-Length بالبايت تلقائياً بترميز UTF-8، وكيف يعرض المختبر محاكاة منطقية مبسّطة لتحول أقسام الرسالة إلى إطاري HEADERS و DATA في HTTP/2 و HTTP/3 (علماً أن الإطارات الفعلية على السلك تكون ثنائية ومضغوطة):
تفصيل تقني متقدم: أشكال هدف الطلب الأربعة (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للاستعلام عن قدرات الخادم ككل بدلاً من مورد محدد.
# 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
# 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