تطوير الويب: HTML وCSS وJavaScript
خروج

الدرس 1 من 17 · HTML وCSS

كيف يعمل الويب: العميل، الخادم، DNS، HTTP والمتصفح

40 د Node.js 22 (Debian, git, npm, python3)

الهدف

أن تفهم، خطوة بخطوة، ما يحدث بين اللحظة التي يكتب فيها زبون www.riad-yasmine.ma في متصفحه واللحظة التي تظهر فيها الصفحة. ستعرف كيف تقرأ عنوان URL، وتشرح دور DNS، وتصف طلب HTTP واستجابته، وتستعمل أدوات المطوّرين في المتصفح وكذلك curl لملاحظة كل ذلك.

أهم النقاط

  • يعمل الويب بنموذج العميل / الخادم (client / server): المتصفح (العميل) يطلب، والخادم يجيب. الخادم لا يبدأ الكلام أبدًا.
  • يتكوّن عنوان URL من البروتوكول، واسم المضيف، والمنفذ، والمسار، والمعاملات، والمرساة.
  • يترجم DNS اسمًا (www.riad-yasmine.ma) إلى عنوان IP (196.200.x.x)، مثل دليل الهاتف.
  • HTTP حوار نصي: طلب (الطريقة + المسار + الترويسات) واستجابة (رمز الحالة + الترويسات + الجسم).
  • HTTPS = HTTP مشفَّر بواسطة TLS: لا أحد بين العميل والخادم يستطيع قراءة المبادلات أو تعديلها.
  • تتيح أدوات المطوّرين (المفتاح F12) رؤية كل طلب، وHTML، وCSS، وأخطاء JavaScript.

1. الصفحة، الموقع، الخادم، محرك البحث

أربع كلمات نخلط بينها كثيرًا:

المصطلح ما هو مثال
صفحة ويب وثيقة يعرضها المتصفح، في عنوان محدّد صفحة «غرفنا»
موقع ويب مجموعة صفحات مترابطة، تحت اسم نطاق واحد كل riad-yasmine.ma
خادم ويب الحاسوب (والبرنامج) الذي يخزّن الموقع ويجيب عن الطلبات خادم VPS في الدار البيضاء مع nginx
محرك بحث موقع يساعد على إيجاد صفحات أخرى Google، Bing

المتصفح (Firefox، Chrome، Edge، Safari) هو العميل: هو الذي يجلب الصفحات ويرسمها على الشاشة.

2. نموذج العميل / الخادم

تخيّل مقهى «Dar Atay» في فاس. الزبون (أنت) يطلب من النادل. يذهب النادل إلى المطبخ، ويعود بالشاي بالنعناع… أو يقول لك «آسف، لم يبق منه شيء». الويب يتبع هذا المخطّط بالضبط:

 Navigateur (client)                          Serveur web
 ───────────────────                          ───────────
 1. « Donne-moi /chambres.html »   ───────▶
                                   ◀───────   2. « Voici le fichier (200 OK) »
 3. lit le HTML, découvre style.css,
    patio.jpg, app.js
 4. « Donne-moi /style.css »        ───────▶
                                   ◀───────   5. « Voici le CSS »
 ... une requête par ressource ...

(Navigateur = المتصفح، Serveur web = خادم الويب؛ 1. «أعطني /chambres.html» ← 2. «هذا هو الملف (200 OK)» ← 3. يقرأ HTML ويكتشف style.css وpatio.jpg وapp.js ← 4. «أعطني /style.css» ← 5. «هذا هو CSS»؛ طلب واحد لكل مورد.)

صفحة واحدة معروضة = في الغالب عشرات الطلبات: HTML أولًا، ثم كل ورقة أنماط، وكل صورة، وكل سكربت، وكل خط.

3. قراءة عنوان URL

https://www.riad-yasmine.ma:443/chambres/suite-atlas.html?lang=fr&nuits=3#tarifs
└─┬──┘   └───────┬─────────┘└┬┘└────────────┬─────────┘ └──────┬──────┘ └─┬──┘
protocole    nom d'hôte    port          chemin           paramètres    ancre

(protocole = البروتوكول، nom d'hôte = اسم المضيف، port = المنفذ، chemin = المسار، paramètres = المعاملات، ancre = المرساة.)

الجزء الدور
https البروتوكول: كيف نتحدّث مع الخادم (http أو https)
www.riad-yasmine.ma اسم المضيف: أيّ خادم نتصل به
:443 المنفذ؛ يُحذف غالبًا لأنه ضمني (80 لـ http، و443 لـ https)
/chambres/suite-atlas.html المسار: أيّ مورد على هذا الخادم
?lang=fr&nuits=3 المعاملات (أزواج مفتاح=قيمة مفصولة بـ &)
#tarifs المرساة: موضع داخل الصفحة؛ لا تُرسَل أبدًا إلى الخادم

في JavaScript (ستراه في المستوى 2)، يقوم الكائن URL بهذا التقسيم نيابة عنك:

const u = new URL("https://www.riad-yasmine.ma/chambres.html?lang=fr");
u.hostname;                 // "www.riad-yasmine.ma"
u.pathname;                 // "/chambres.html"
u.searchParams.get("lang"); // "fr"

4. DNS: دليل الويب

تتعرّف الحواسيب على بعضها بفضل عناوين IP (196.200.131.10، أو في IPv6 2a01:4f8::1). أما البشر فيفضّلون الأسماء. ويقوم DNS (Domain Name System، نظام أسماء النطاقات) بالترجمة.

عندما تزور www.riad-yasmine.ma لأول مرة:

  1. ينظر المتصفح في ذاكرته المؤقتة (cache)؛ ثم ينظر النظام في الملف /etc/hosts (Linux) أو C:\Windows\System32\drivers\etc\hosts (Windows)؛
  2. وإلا، فإنه يستعلم محلّل DNS (resolver) الخاص بمزوّدك (Maroc Telecom، inwi، Orange) أو محلّلًا عموميًا؛
  3. يسأل المحلّل خوادم الجذر (root)، التي توجّهه إلى خوادم .ma (التي تديرها ANRT)، والتي توجّهه بدورها إلى خوادم DNS الخاصة بالنطاق riad-yasmine.ma؛
  4. تعطي هذه الأخيرة الجواب النهائي: عنوان IP. ويُحتفَظ به في الذاكرة المؤقتة مدة معيّنة (TTL).

أكثر سجلات DNS شيوعًا:

النوع الدور مثال
A اسم ← عنوان IPv4 www A 196.200.131.10
AAAA اسم ← عنوان IPv6 www AAAA 2a01:4f8::1
CNAME اسم مستعار يشير إلى اسم آخر boutique CNAME shops.exemple.com
MX خادم البريد الخاص بالنطاق @ MX 10 mail.riad-yasmine.ma
TXT نص حر (عمليات تحقق، SPF…) @ TXT "v=spf1 mx -all"

لاستعلام DNS من الطرفية:

nslookup www.riad-yasmine.ma        # Windows وLinux وmacOS
dig +short www.riad-yasmine.ma      # Linux (الحزمة dnsutils / bind-utils)
getent hosts localhost              # ما يراه النظام، بما في ذلك /etc/hosts

5. HTTP: الطلب

بمجرد معرفة عنوان IP، يفتح المتصفح اتصالًا (TCP، المنفذ 443 لـ https) ويرسل طلب HTTP. وهو نص:

GET /chambres.html HTTP/1.1
Host: www.riad-yasmine.ma
User-Agent: Mozilla/5.0 (Windows NT 10.0) Firefox/131.0
Accept: text/html
Accept-Language: fr-MA,fr;q=0.9,ar;q=0.8
  • سطر الطلب: الطريقة، والمسار، والإصدار؛
  • الترويسات (headers): معلومة واحدة في كل سطر، Nom: valeur (الاسم: القيمة). الترويسة Host إلزامية في HTTP/1.1: فالخادم نفسه يستضيف في الغالب عدة مواقع؛
  • سطر فارغ، ثم ربما جسم (body) (لإرسال استمارة، مثلًا).

الطرق الرئيسية:

الطريقة الاستعمال مثال
GET قراءة مورد عرض قائمة الغرف
POST إنشاء / إرسال بيانات إرسال استمارة الحجز
PUT / PATCH استبدال / تعديل تغيير تواريخ حجز
DELETE حذف إلغاء حجز
HEAD مثل GET، لكن دون الجسم التحقق من وجود صفحة

6. HTTP: الاستجابة ورموز الحالة

HTTP/1.1 200 OK
Content-Type: text/html; charset=utf-8
Content-Length: 5120
Cache-Control: max-age=600

<!doctype html>
<html lang="fr"> ...

يلخّص رمز الحالة (status code) (3 أرقام) النتيجة. ويحدّد الرقم الأول العائلة:

العائلة المعنى رموز يجب معرفتها
2xx نجاح 200 OK، 201 Created، 204 No Content
3xx إعادة توجيه 301 Moved Permanently، 302 Found، 304 Not Modified
4xx خطأ من العميل 400 Bad Request، 401 Unauthorized، 403 Forbidden، 404 Not Found
5xx خطأ من الخادم 500 Internal Server Error، 502 Bad Gateway، 503 Service Unavailable

احفظ القاعدة: 4xx = الطلب هو الذي فيه مشكلة (عنوان خاطئ، لا توجد صلاحية)، 5xx = الخادم هو الذي تعطّل. عندما يعرض متجر الصناعة التقليدية صفحة بيضاء مع 500، لا فائدة من التحقق من العنوان: يجب قراءة سجلات الخادم.

تشير الترويسة Content-Type إلى طبيعة الجسم: text/html، text/css، application/javascript، image/webp، application/json… ويستعملها المتصفح ليعرف ماذا يفعل بالمحتوى.

7. HTTPS: القفل

في HTTP العادي، كل شيء ينتقل بشكل مكشوف: على شبكة Wi-Fi في مقهى، يمكن لجار سيّئ النية أن يقرأ كلمة المرور المكتوبة في موقعك أو أن يعدّل الصفحة. يضيف HTTPS طبقة تشفير (TLS):

  • يقدّم الخادم شهادة (certificate) تثبت هويته (تُصدرها جهة معتمدة، مثل Let's Encrypt المجانية)؛
  • يتّفق المتصفح والخادم على مفتاح سرّي؛
  • بقية المبادلة كلها مشفَّرة.

اليوم، يُوسَم الموقع الذي لا يستعمل HTTPS بعبارة «غير آمن» في المتصفحات، ويكون ترتيبه في محركات البحث أضعف، وبعض الوظائف (تحديد الموقع الجغرافي، الإشعارات…) ممنوعة فيه. يجب أن يكون كل موقع بـ HTTPS، حتى لو كان مجرد واجهة تعريفية.

8. ماذا يفعل المتصفح بالاستجابة

استلام HTML ليس إلا البداية. فالمتصفح:

  1. يحلّل HTML ويبني شجرة كائنات، هي DOM (Document Object Model، نموذج كائن المستند)؛
  2. يكتشف الموارد المرتبطة (<link>، <img>، <script>) ويطلبها؛
  3. يحلّل CSS ويحسب نمط كل عنصر؛
  4. يحسب التخطيط (layout) (موضع كل صندوق وحجمه)؛
  5. يرسم البكسلات على الشاشة؛
  6. ينفّذ JavaScript، الذي يمكن أن يعدّل DOM… ويتسبّب في حساب جديد للتخطيط.

لهذا يهمّ ترتيب الملفات وحجمها: سكربت كبير موضوع في أعلى الصفحة يعطّل العرض (الدرس 4.2).

9. أدوات المطوّرين في المتصفح

اضغط على F12 (أو نقرة يمنى ← «Inspecter»، أي «فحص») في Firefox أو Chrome أو Edge. التبويبات الأساسية:

التبويب ما فائدته
العناصر / المفتش (Inspecteur) رؤية DOM وCSS المطبَّق، وتعديلهما مباشرة
وحدة التحكم (Console) قراءة أخطاء JavaScript، وكتابة شيفرة JS
الشبكة (Réseau) رؤية كل طلب: الطريقة، الحالة، الحجم، المدة، الترويسات
التطبيق / التخزين ملفات تعريف الارتباط (cookies)، localStorage (الدرس 3.3)
Lighthouse تدقيق الأداء وسهولة الوصول (الدرس 4.2)

تمرين تقوم به على حاسوبك: افتح موقعًا مغربيًا تعرفه، التبويب الشبكة، وأعد التحميل (Ctrl+F5). حدّد الطلب الأول (HTML)، ورمز حالته، وContent-Type الخاص به، ثم عُدّ الصور. فعّل خيار «Désactiver le cache» (تعطيل الذاكرة المؤقتة) واختر تقييدًا من نوع «3G»: سترى ما يعيشه الزبائن على شبكة جوّال بطيئة.

10. ملاحظة HTTP من سطر الأوامر باستعمال curl

curl هو السكين السويسري لمطوّر الويب: يرسل طلبات HTTP من الطرفية.

curl http://127.0.0.1:8080/                 # يعرض الجسم (HTML)
curl -i http://127.0.0.1:8080/              # -i: الترويسات + الجسم
curl -I http://127.0.0.1:8080/              # -I: طلب HEAD، الترويسات فقط
curl -v http://127.0.0.1:8080/              # -v: الحوار كله (> مُرسَل، < مُستلَم)
curl -L http://127.0.0.1:8080/promo         # -L: تتبّع إعادات التوجيه
curl -X POST -d "nom=Amina" http://127.0.0.1:8080/reserver   # إرسال بيانات

مع -v، الأسطر التي تبدأ بـ > هي ما ترسله أنت، والتي تبدأ بـ < هي ما يجيب به الخادم. وهذا بالضبط ما يعرضه تبويب الشبكة في المتصفح.

11. خادم ويب صغير بـ Node.js

أثناء التطوير، نشغّل خادمًا على حاسوبنا نفسه: يستمع على العنوان 127.0.0.1 (أو localhost)، الذي يعني دائمًا «أنا نفسي». هذه هي خلاصة الخادم المرفق في التمرين التطبيقي:

const http = require("http");
const serveur = http.createServer((req, res) => {
  if (req.url === "/") {
    res.writeHead(200, { "Content-Type": "text/html; charset=utf-8" });
    res.end("<h1>Bienvenue au Riad Yasmine</h1>");
  } else {
    res.writeHead(404, { "Content-Type": "text/plain; charset=utf-8" });
    res.end("Page introuvable");
  }
});
serveur.listen(8080, "127.0.0.1");

لا تحتاج بعد إلى فهم كل سطر: احفظ أن خادم الويب يستقبل طلبًا (req)، ويختار رمز حالة وترويسات، ثم يرسل جسمًا (res.end). ويقوم Nginx أو Apache أو Express بالشيء نفسه، بشكل أكمل بكثير.

node serveur.js &                  # تشغيل الخادم في الخلفية
curl -i http://127.0.0.1:8080/     # اختباره
kill %1                            # إيقافه (أو: kill PID)

أخطاء متكررة

  • الخلط بين 4xx و5xx: يأتي 404 من عنوان خاطئ أو ملف غير موجود؛ ويأتي 500 من خطأ في شيفرة الخادم.
  • نسيان وجود الذاكرة المؤقتة: بعد تعديل، قد يعرض المتصفح النسخة القديمة. أعد التحميل بـ Ctrl+F5 أو فعّل «Désactiver le cache» في تبويب الشبكة.
  • الاعتقاد أن المرساة (#tarifs) تُرسَل إلى الخادم: تبقى في المتصفح.
  • تغيير سجل DNS وانتظار أثر فوري: تبقى الأجوبة القديمة في الذاكرة المؤقتة طوال مدة TTL (أحيانًا عدة ساعات).

التطبيق العملي (Lab)

خادم ويب بسيط لـ Riad Yasmine جاهز في /root/web/serveur.js. ستقوم بما يلي:

  1. كتابة طلب HTTP يدويًا في ملف، لتتعرّف جيدًا على شكله؛
  2. تشغيل الخادم في الخلفية وتسجيل ترويسات استجابته باستعمال curl -I؛
  3. ملاحظة إعادة توجيه 301 وترويستها Location؛
  4. إحداث خطأ 404 وتسجيل الاستجابة الكاملة.

نصيحة: عندما يعمل الخادم في الخلفية، يعرض كل طلب يستقبله في الطرفية. أوقفه بـ kill %1 عندما تنتهي.

اختبار قصير

  1. ما أجزاء عنوان URL التالي https://boutique-fes.ma/tapis?couleur=rouge#avis؟
  2. ما فائدة DNS؟
  3. ماذا تعني الرموز 301 و404 و500؟
  4. لماذا تُعدّ الترويسة Host ضرورية في طلب HTTP/1.1؟
  5. أيّ تبويب من أدوات المطوّرين تستعمل لمعرفة سبب عدم ظهور صورة؟
الأجوبة
  1. البروتوكول https، اسم المضيف boutique-fes.ma، المسار /tapis، المعامل couleur=rouge، المرساة avis (المنفذ 443 ضمني).
  2. ترجمة اسم نطاق إلى عنوان IP، حتى يعرف المتصفح بأيّ خادم يتصل.
  3. 301: نُقل المورد نهائيًا (تعطي الترويسة Location العنوان الجديد)؛ 404: المورد غير موجود؛ 500: خطأ داخلي في الخادم.
  4. لأن عنوان IP واحدًا يستضيف في الغالب عدة مواقع: تشير Host إلى الخادم أيّ موقع نطلب.
  5. تبويب الشبكة: يعرض طلب الصورة، ورمز حالته (404؟) وعنوانه الدقيق. كما تشير وحدة التحكم (Console) في الغالب إلى الخطأ.

مصادر مرجعية: MDN Web Docs بالفرنسية (رخصة CC BY-SA 2.5). نص أصلي من MasterLinux.

تمارين تطبيقية

تُنجَز على Node.js 22 (Debian, git, npm, python3)

الطرفية عبر الإنترنت قادمة قريبًا. في انتظار ذلك، أنجِز هذه المهام على جهازك بنظام لينكس أو على آلة افتراضية أو WSL.

  1. اكتب في /root/web/requete.txt طلب HTTP الذي سيرسله متصفح للحصول على الصفحة /chambres.html من الموقع www.riad-yasmine.ma: أولًا سطر الطلب (الطريقة GET، المسار، الإصدار HTTP/1.1)، ثم الترويسة Host في السطر الموالي.
    عرض تلميحprintf '%s\n' 'GET /chambres.html HTTP/1.1' 'Host: www.riad-yasmine.ma' > /root/web/requete.txt
    عرض الحل
    printf "%s\n" "GET /chambres.html HTTP/1.1" "Host: www.riad-yasmine.ma" "Accept: text/html" > /root/web/requete.txt

    التحقق : grep -q "^GET /chambres.html HTTP/1.1" /root/web/requete.txt && grep -qi "^host: *www.riad-yasmine.ma" /root/web/requete.txt

  2. شغّل الخادم المرفق في الخلفية (node /root/web/serveur.js &)، ثم سجّل في /root/web/entetes.txt سطر الحالة وترويسات الاستجابة للصفحة الرئيسية http://127.0.0.1:8080/.
    عرض تلميحيعرض curl -I (أو curl -i) سطر الحالة والترويسات: curl -sI http://127.0.0.1:8080/ > /root/web/entetes.txt
    عرض الحل
    node /root/web/serveur.js >/dev/null 2>&1 & p=$!; sleep 1; curl -sI http://127.0.0.1:8080/ > /root/web/entetes.txt; kill $p

    التحقق : grep -q "^HTTP/1.1 200" /root/web/entetes.txt && grep -qi "^content-type: *text/html" /root/web/entetes.txt

  3. نُقلت الصفحة القديمة /promo-ramadan. سجّل في /root/web/redirection.txt استجابة الخادم لهذا العنوان (الحالة والترويسات): يجب أن نقرأ فيها رمز إعادة التوجيه والترويسة Location.
    عرض تلميحلا تتبع إعادة التوجيه: curl -sI دون الخيار -L.
    عرض الحل
    node /root/web/serveur.js >/dev/null 2>&1 & p=$!; sleep 1; curl -sI http://127.0.0.1:8080/promo-ramadan > /root/web/redirection.txt; kill $p

    التحقق : grep -q "^HTTP/1.1 301" /root/web/redirection.txt && grep -qi "^location: */offres.html" /root/web/redirection.txt

  4. سجّل في /root/web/introuvable.txt الاستجابة الكاملة (الترويسات والجسم معًا) للخادم بالنسبة للعنوان http://127.0.0.1:8080/chambre-inexistante.
    عرض تلميحيعرض curl -si الترويسات ثم جسم الاستجابة.
    عرض الحل
    node /root/web/serveur.js >/dev/null 2>&1 & p=$!; sleep 1; curl -si http://127.0.0.1:8080/chambre-inexistante > /root/web/introuvable.txt; kill $p

    التحقق : grep -q "^HTTP/1.1 404" /root/web/introuvable.txt && grep -q "Page introuvable" /root/web/introuvable.txt

المراجع الرسمية المعتمدة: Comment fonctionne le Web — https://developer.mozilla.org/fr/docs/Learn_web_development/Getting_started/Web_standards/How_the_web_works ; Comment les navigateurs chargent les sites web — https://developer.mozilla.org/fr/docs/Learn_web_development/Getting_started/Web_standards/How_browsers_load_websites ; Naviguer sur le Web — https://developer.mozilla.org/fr/docs/Learn_web_development/Getting_started/Environment_setup/Browsing_the_web ; Installation des outils de base — https://developer.mozilla.org/fr/docs/Learn_web_development/Getting_started/Environment_setup/Installing_software. نص أصلي من MasterLinux.