قبل أن تظهر أي صفحة على الشاشة، يجري تبادل بين برنامجين: برنامج على جهاز القارئ يطلب شيئا، وبرنامج على خادم بعيد يجيبه. والقواعد التي تنظم هذا التبادل هي بروتوكول HTTP.
قد لا يكون فريق واحد قد كتب البرنامجين، وقد يختلفان في لغة البرمجة ونظام التشغيل ويفصل بينهما نصف الكرة الأرضية. ومع ذلك يعرف الخادم ما طلب منه وماذا يفعل به، ويعرف المتصفح هل نجح طلبه أم فشل، وما نوع البيانات التي وصلته وكيف يعرضها. لا ينشأ هذا التفاهم مصادفة؛ بل يصنعه اتفاق مكتوب يلتزم به الطرفان قبل أن يتبادلا الرسائل.

لا تفاهم بين برنامجين بلا قواعد مكتوبة
إذا وصلت الشبكة بين برنامجين، صار كل منهما قادرا على إرسال سلسلة من البايتات (bytes) إلى الآخر؛ أي بيانات خام لا تحمل معناها بنفسها. لكن القدرة على الإرسال وحدها لا تصنع حوارا. فما زالت أسئلة أساسية بلا جواب: من يتكلم أولا؟ وكيف يحدد الأول ما يريده؟ وكيف يخبره الثاني بأنه لم يجد المطلوب، بدلا من صمت يحتمل أكثر من تفسير؟ وإذا أرسل إليه شيئا، فكيف يعرف الأول أن ما وصله صورة لا نص؟
لا بد أن يتفق الطرفان مسبقا على جواب كل سؤال، لأن الرسالة الواصلة لا تشرح نفسها. تسمى مجموعة القواعد التي تحدد شكل الرسائل ومعانيها وترتيب الأدوار بين الطرفين بروتوكولا (protocol). ولا يفرض البروتوكول لغة برمجة أو نظام تشغيل أو بنية معينة للبرنامج؛ إنما يحدد ما يظهر على الشبكة: هذا الشكل من الرسائل يحمل هذا المعنى. لذلك يستطيع متصفح كتب بلغة أن يتفاهم مع خادم كتب بلغة أخرى، ما دام كلاهما يصوغ رسائله وفق القواعد نفسها.
ما هو HTTP؟ عميل يسأل وخادم يجيب
يعني الاسم بروتوكول نقل النص التشعبي (Hypertext Transfer Protocol, HTTP). والنص التشعبي (hypertext) نص تتخلله روابط تنقل القارئ إلى نص آخر، ومن أجل نقل هذا النوع من النصوص وضع البروتوكول أول مرة مع ولادة الويب مطلع التسعينيات. اتسع استعماله بعد ذلك ليشمل الصور والملفات والفيديو وبيانات التطبيقات، لكن الاسم بقي على أصله.
يقوم HTTP في جوهره على رسالتين: يرسل طرف رسالة يطلب بها شيئا، فيرد الطرف الآخر برسالة ثانية. تسمى الأولى الطلب (request)، وتسمى الثانية الاستجابة (response). أما الطرف الذي يفتح الاتصال ويرسل الطلب فهو العميل (client)، والطرف الذي ينتظر الطلبات ويجيب عنها فهو الخادم (server).
العميل والخادم دوران في تبادل واحد، وليسا صفتين ثابتتين لجهاز بعينه. فقد يكون البرنامج نفسه خادما في اتصال وعميلا في اتصال آخر: حين يرد خادم موقع على طلب زائر يؤدي دور الخادم، ثم يؤدي دور العميل عندما يحتاج إلى بيانات من خدمة أخرى فيرسل إليها طلبا. إذن يحدد موضع البرنامج في التبادل الجاري دوره، لا نوع الجهاز الذي يعمل عليه.
ويبدأ العميل هذا التبادل دائما. فالخادم لا يرسل في HTTP استجابة لم يطلبها العميل؛ بل ينتظر الطلب ثم يجيب عنه.
يسمي البروتوكول ما يطلبه العميل موردا (resource). والمورد هو كل ما يمكن الإشارة إليه بعنوان ثم طلبه: صفحة أو صورة أو ملف، أو سجل في قاعدة بيانات، أو نتيجة عملية يجريها الخادم عند كل طلب. لا يهتم HTTP بطبيعة المورد ولا بكيفية توليده؛ بل يحدد كيف يطلب وكيف يوصف ما يعود عنه. فقد يقرأ الخادم ملفا جاهزا من قرصه، أو يبني الجواب من قاعدة بيانات في تلك اللحظة. لا يرى العميل هذا الفرق ولا يحتاج إلى معرفته؛ فهو يرسل طلبا إلى عنوان ثم يقرأ ما يعود إليه.
ماذا يحمل الطلب وماذا تحمل الاستجابة
يحدد العميل في كل طلب شيئين على الأقل: المورد الذي يقصده، والفعل الذي يريده عليه. يسمى هذا الفعل الطريقة (method)، وهي كلمة قصيرة مثل GET أو POST تحدد هل يريد العميل قراءة المورد أم إرسال بيانات إليه. ويحمل الطلب أيضا بيانات وصفية في حقول تسمى الترويسات (headers)، وقد يحمل جسما (body) يتضمن البيانات المرسلة.
أما في الاستجابة، فيبين الخادم ما جرى برقم من ثلاث خانات يسمى رمز الحالة (status code): مثل 200 لطلب نجح و404 لمورد لم يوجد، وغيرهما. ويرسل مع الرمز ترويسات تصف الجواب، وجسما يحمل المورد المطلوب إذا كان للجواب جسم.
لكل من هذه الأسماء الأربعة — الطريقة ورمز الحالة والترويسة والجسم — دلالات تفرد لها مواضع أخرى من هذه الدورة. ويكفي هنا أن يتضح شكل الحوار: سؤال يحدد المورد والفعل المطلوب عليه، وجواب يبين نتيجة السؤال ويحمل معه ما طلب.
ما يحدده HTTP وما يتركه لغيره
يحدد HTTP معنى الرسالتين وشكلهما، لكنه لا يتولى إيصالهما بنفسه. فهو يفترض وجود قناة نقل موثوقة بين الطرفين: ما يرسله أحدهما يصل إلى الآخر كاملا، وبالترتيب نفسه، من دون نقص أو خلط. يوفر هذه القناة بروتوكول يعمل تحته: بروتوكول التحكم في النقل (Transmission Control Protocol, TCP) في معظم الاتصالات اليوم، وQUIC في أحدث نسخة من HTTP.
لهذا يوصف HTTP بأنه بروتوكول في طبقة التطبيقات (application layer). وتعني الطبقات هنا تقسيم العمل بين بروتوكولات يعمل بعضها فوق بعض: تتولى الطبقة الأدنى إيصال البايتات سليمة بين جهازين، بينما تحدد الطبقة الأعلى — ومنها HTTP — معنى هذه البايتات: ماذا يطلب العميل، وماذا يعني جواب الخادم. فكل طبقة تبني على ما تحتها بدلا من تكرار عمله.
ولهذا الفصل أثر عملي: أمكن تغيير طريقة النقل من نسخة إلى أخرى من دون تغيير معاني الرسائل. وأمكن كذلك وضع HTTP على قناة مشفرة فيصير HTTPS؛ فلا يستطيع من تمر عبره الرسائل في الطريق الاطلاع عليها، بينما تبقى دلالاتها كما هي.
الصفحة الواحدة عشرات التبادلات المستقلة
لنأخذ صفحة مقال واحدة على موقع. يرسل المتصفح أولا طلبا لمستند الصفحة، فيرد الخادم بالمستند. لكن هذا المستند لا يكفي لعرض الصفحة كاملة؛ إذ يشير إلى ملف التنسيق والخط وكل صورة وملفات جافاسكربت التي تشغلها الصفحة. يقرأ المتصفح هذه الإشارات، ويرسل طلبا جديدا لكل مورد، ثم يتلقى كل جواب في استجابة مستقلة.
قد يكون عدد الطلبات كبيرا. ففي قياسات مشروع HTTP Archive لسنة 2025، بلغ عدد الطلبات في الصفحة الوسيطة — أي الصفحة التي تقع في منتصف الترتيب — 77 طلبا على الحاسوب المكتبي و72 على الهاتف. وما يراه القارئ صفحة واحدة يراه البروتوكول عشرات التبادلات، يتكون كل واحد منها من طلب واستجابة قائمين بذاتهما.
لكن استقلال هذه الطلبات أهم من عددها. فالخادم لا يستقبل «طلب صفحة» ثم ملحقاتها بوصفها مجموعة واحدة؛ بل يستقبل طلبات متتابعة، يحدد كل واحد منها المورد المطلوب كاملا كأنه أول طلب يصل إليه.
لا يحفظ حالة: كل طلب يفهم وحده
هذا الاستقلال صفة مقصودة في تصميم HTTP، ويعبر عنها بأنه بروتوكول لا يحفظ حالة (stateless). وللصفة معنى دقيق في المواصفة: يحمل كل طلب ما يكفي لفهمه، فلا يتوقف تفسيره على طلب سابق أو على الاتصال الذي مر عبره. بل لا يجوز للخادم أن يفترض أن طلبين وصلا عبر اتصال واحد قد صدرا عن العميل نفسه، إلا إذا كان الاتصال مشفرا ومخصصا لذلك العميل وحده.
رافقت هذه الصفة البروتوكول منذ بدايته. ففي صيغته الأولى سنة 1991، كان الخادم يقطع الاتصال بمجرد انتهائه من إرسال المستند. وتنص وثيقة تلك الصيغة على أنه لا يحتاج بعد ذلك إلى حفظ أي معلومة عن الطلب.
لهذا التصميم كلفة واضحة: يحمل كل طلب سياقه معه، فيكرر في كل مرة ما يحتاجه الخادم لفهمه. لكنه يمنح النظام مرونة كبيرة. فالموقع الذي يخدم ملايين الزوار لا يعمل عادة على خادم واحد، بل على عدة خوادم متكافئة خلف عنوان واحد، يوزع الطلبات بينها موازن حمل (load balancer).
يوضح مثال صغير هذه المرونة. لنفترض أن موقعا يعمل على خمسة خوادم متكافئة، وأن المتصفح أرسل طلبا للصفحة ثم طلبا لصورة داخلها. لا يلزم أن يجيب خادم واحد عن الطلبين؛ فالطلب الثاني مكتف بذاته ولا يحتاج إلى سياق محفوظ لدى خادم معين، ولذلك يستطيع أي خادم من الخمسة أن يجيبه. ولو كان HTTP يحفظ حالة، لوجب أن يعود كل طلب إلى الخادم الذي يحتفظ ببقية المحادثة، ولانقطع عمل الموقع عند الزائر كلما تعطل ذلك الخادم بعينه.
إذا كان البروتوكول لا يربط الطلبات، فكيف يعرف الموقع أنك صاحب الطلب الثاني بعد أن سجلت دخولك في طلب سابق؟ يعيد العميل مع كل طلب إرسال معلومة تعرف به، مستخدما آلية بنيت فوق البروتوكول لا داخله. ولهذه الآلية درس مستقل في الدورة.
ولا يعني انعدام الحالة أن الاتصال يفتح ويغلق مع كل طلب. فإدارة الاتصال مسألة مستقلة تعالجها كل نسخة بطريقتها، أما ربط الطلبات بعضها ببعض فمسألة أخرى لا يتولاها البروتوكول أصلا.
خريطة النسخ: ما الذي تغير وما الذي بقي
يعمل HTTP على الويب منذ أكثر من ثلاثة عقود، وله اليوم ثلاث نسخ رئيسية مستخدمة في الوقت نفسه. ويكشف تاريخ هذه النسخ ما الذي تغير في البروتوكول وما الذي ظل ثابتا.
- HTTP/0.9 (1991): كانت أبسط صيغة. يتكون الطلب من سطر واحد يحمل كلمة GET ومسار المستند، أما الجواب فهو مستند HTML فقط، بلا ترويسات أو رموز حالة. ويقطع الخادم الاتصال بعد إرساله. ولأن الجواب لا يتضمن رمز حالة، كان الفشل يظهر في صورة نص داخل الجواب، لا علامة يستطيع البرنامج قراءتها.
- HTTP/1.0 (RFC 1945، مايو 1996): أضافت هذه النسخة الترويسات ورمز الحالة ورقم النسخة إلى الرسالة. وبفضل الترويسة التي تصف نوع المحتوى، صار نقل الصور والملفات وغيرها ممكنا، فلم يعد البروتوكول مقتصرا على المستندات النصية بصيغة HTML.
- HTTP/1.1 (معيارا سنة 1997، ثم مراجعات 1999 و2014، ونصه الحالي RFC 9112 سنة 2022): استقرت الشبكة على هذه النسخة نحو عشرين سنة. أضافت ترويسة المضيف (Host)، فأمكن أن تسكن عدة مواقع على عنوان واحد. وأضافت أيضا الاتصال الدائم بين الطلبات، وضوابط التخزين المؤقت، والطلبات الشرطية، وطلبات المدى، والتفاوض على المحتوى.
- HTTP/2 (RFC 7540 سنة 2015، ونصه الحالي RFC 9113 سنة 2022): لم تغير هذه النسخة معاني الطرق أو رموز الحالة، بل غيرت صياغة الرسالة على القناة إلى صيغة ثنائية تتيح إرسال رسائل متزامنة عبر اتصال واحد وضغط الترويسات المتكررة. وهي النسخة الوحيدة التي أتاحت الخروج على قاعدة «لا استجابة بلا طلب» من خلال الدفع من الخادم (server push)، حيث يرسل الخادم إلى العميل استجابات لم يطلبها. ثم تبين أن فائدته محدودة، فتخلت عنه المتصفحات: أوقفه Chrome سنة 2022، وأزاله Firefox سنة 2024.
- HTTP/3 (RFC 9114 سنة 2022): غيرت هذه النسخة طبقة النقل أيضا، لا المعنى. فهي تنقل الرسائل عبر QUIC (RFC 9000 سنة 2021) بدلا من TCP. ويعمل QUIC فوق UDP، ويوفر بنفسه قناة النقل الموثوقة.
تشترك النسخ الثلاث المستخدمة اليوم في الدلالات نفسها. فقد فصلت المواصفة الحالية تعريف الدلالات — أي معاني الطرق ورموز الحالة والترويسات — في وثيقة مستقلة هي RFC 9110، وتركت لكل نسخة وثيقة تشرح كيفية صياغة الرسالة ونقلها. ولهذا الفصل نتيجة عملية: يستطيع وسيط في الطريق استقبال الرسالة بنسخة ثم إعادة إرسالها بنسخة أخرى من دون تغيير معناها. فطلب GET في HTTP/1.1 هو طلب GET نفسه في HTTP/3، والرمز 404 يحمل المعنى نفسه في النسخ الثلاث.
لم تلغ أي نسخة النسخة التي سبقتها؛ فالنسخ الثلاث باقية لأن لكل واحدة مواضع تناسبها. لا يزال HTTP/1.1 حاضرا في خوادم كثيرة وفي الاتصال بين الخدمات. وتدعم المتصفحات الحديثة HTTP/2 وHTTP/3: يتوفر دعم HTTP/3 في Chrome منذ الإصدار 87، وفي Firefox منذ 88، وفي Safari منذ 16، وتدعمه متصفحات يستخدمها نحو 94 في المئة من مستخدمي الويب. أما كيفية اتفاق الطرفين على النسخة التي سيتحادثان بها في كل مرة فلها آلية مستقلة يفصلها درس لاحق.
البروتوكول الذي ينسى
يقوم الويب كله على بروتوكول ينسى: لا يتذكر شيئا من طلبك السابق، ولا يعرف أن عشرات الطلبات التي وصلته قبل لحظات كانت صفحة واحدة في نظر القارئ.
ساعد هذا النسيان المتعمد الويب على التوسع: بما أن كل طلب مكتف بذاته، يستطيع أي خادم أن يجيب عنه، ويستطيع أي وسيط أن ينقله، كما يستطيع البروتوكول تغيير طريقة النقل من دون تغيير المعنى. وفي المقابل، يجب أن يحمل الطلب نفسه كل ما يحتاجه الخادم لفهمه: من تكون، وأي نسخة من المورد تريد، وبأي شروط تقبلها.
لهذا تتركز معرفة المطور بـHTTP في دلالات ما يوضع داخل الطلب والاستجابة: الطرق والرموز والترويسات. وتبقى هذه المعرفة صالحة حين تتبدل النسخة المستخدمة، لأن طريقة النقل هي التي تتغير بين النسخ، أما المعنى فيبقى ثابتا.

