الدرس 1 من 17 · HTML وCSS
كيف يعمل الويب: العميل، الخادم، DNS، HTTP والمتصفح
الهدف
أن تفهم، خطوة بخطوة، ما يحدث بين اللحظة التي يكتب فيها زبون 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 لأول مرة:
- ينظر المتصفح في ذاكرته المؤقتة (cache)؛ ثم ينظر النظام في الملف
/etc/hosts(Linux) أوC:\Windows\System32\drivers\etc\hosts(Windows)؛ - وإلا، فإنه يستعلم محلّل DNS (resolver) الخاص بمزوّدك (Maroc Telecom، inwi، Orange) أو محلّلًا عموميًا؛
- يسأل المحلّل خوادم الجذر (root)، التي توجّهه إلى خوادم
.ma(التي تديرها ANRT)، والتي توجّهه بدورها إلى خوادم DNS الخاصة بالنطاقriad-yasmine.ma؛ - تعطي هذه الأخيرة الجواب النهائي: عنوان 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 ليس إلا البداية. فالمتصفح:
- يحلّل HTML ويبني شجرة كائنات، هي DOM (Document Object Model، نموذج كائن المستند)؛
- يكتشف الموارد المرتبطة (
<link>،<img>،<script>) ويطلبها؛ - يحلّل CSS ويحسب نمط كل عنصر؛
- يحسب التخطيط (layout) (موضع كل صندوق وحجمه)؛
- يرسم البكسلات على الشاشة؛
- ينفّذ 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. ستقوم بما يلي:
- كتابة طلب HTTP يدويًا في ملف، لتتعرّف جيدًا على شكله؛
- تشغيل الخادم في الخلفية وتسجيل ترويسات استجابته باستعمال
curl -I؛ - ملاحظة إعادة توجيه 301 وترويستها
Location؛ - إحداث خطأ 404 وتسجيل الاستجابة الكاملة.
نصيحة: عندما يعمل الخادم في الخلفية، يعرض كل طلب يستقبله في الطرفية. أوقفه بـ kill %1 عندما تنتهي.
اختبار قصير
- ما أجزاء عنوان URL التالي
https://boutique-fes.ma/tapis?couleur=rouge#avis؟ - ما فائدة DNS؟
- ماذا تعني الرموز 301 و404 و500؟
- لماذا تُعدّ الترويسة
Hostضرورية في طلب HTTP/1.1؟ - أيّ تبويب من أدوات المطوّرين تستعمل لمعرفة سبب عدم ظهور صورة؟
الأجوبة
- البروتوكول
https، اسم المضيفboutique-fes.ma، المسار/tapis، المعاملcouleur=rouge، المرساةavis(المنفذ 443 ضمني). - ترجمة اسم نطاق إلى عنوان IP، حتى يعرف المتصفح بأيّ خادم يتصل.
- 301: نُقل المورد نهائيًا (تعطي الترويسة
Locationالعنوان الجديد)؛ 404: المورد غير موجود؛ 500: خطأ داخلي في الخادم. - لأن عنوان IP واحدًا يستضيف في الغالب عدة مواقع: تشير
Hostإلى الخادم أيّ موقع نطلب. - تبويب الشبكة: يعرض طلب الصورة، ورمز حالته (404؟) وعنوانه الدقيق. كما تشير وحدة التحكم (Console) في الغالب إلى الخطأ.
مصادر مرجعية: MDN Web Docs بالفرنسية (رخصة CC BY-SA 2.5). نص أصلي من MasterLinux.