ماذا سنتعلم اليوم؟ سنتعلم كيفية توجيه المسارات الأساسية (Routing) في Node.js لتقديم صفحات HTML مختلفة بناءً على طلبات المستخدمين، مما يفتح الباب لتطبيقات ويب تفاعلية.
الخطوة 1: تهيئة المشروع وإنشاء ملفات HTML الأساسية
سنبدأ بإنشاء مجلد جديد للمشروع وتهيئة Node.js فيه. ثم سنقوم بإنشاء ملفات HTML التي سنقوم بعرضها.
إنشاء مجلد المشروع وتهيئة Node.js:
افتح سطر الأوامر (Terminal) ونفذ الأوامر التالية:
mkdir basic-routing-app
cd basic-routing-app
npm init -y
إنشاء ملفات HTML:
قم بإنشاء ملفين باسم index.html و about.html داخل مجلد basic-routing-app. هذا هو محتوى كل منهما:
index.html:
<!DOCTYPE html>
<html lang="ar">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>الصفحة الرئيسية</title>
</head>
<body>
<h1>مرحباً بك في الصفحة الرئيسية!</h1>
<p>هذه هي صفحة الهبوط الافتراضية.</p>
<a href="/about">اذهب إلى صفحة من نحن</a>
</body>
</html>
about.html:
<!DOCTYPE html>
<html lang="ar">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>من نحن</title>
</head>
<body>
<h1>عن شركتنا</h1>
<p>نحن نقدم أفضل الحلول البرمجية.</p>
<a href="/">العودة إلى الصفحة الرئيسية</a>
</body>
</html>
الخطوة 2: إنشاء خادم HTTP بسيط وقراءة الملفات
الآن، سنقوم بإنشاء ملف index.js وهو ملف الخادم الرئيسي. سنستخدم وحدة http لإنشاء الخادم ووحدة fs لقراءة ملفات HTML.
قم بإنشاء ملف index.js في نفس المجلد واضف الكود التالي:
const http = require('http'); // استيراد وحدة HTTP لإنشاء خادم الويب
const fs = require('fs'); // استيراد وحدة File System لقراءة الملفات
const path = require('path'); // استيراد وحدة Path للتعامل مع مسارات الملفات
const PORT = 3000; // تحديد المنفذ الذي سيعمل عليه الخادم
// إنشاء الخادم
const server = http.createServer((req, res) => {
// تعيين رأس الاستجابة (Header) لـ HTML
res.writeHead(200, { 'Content-Type': 'text/html; charset=utf-8' });
// قراءة ملف index.html وإرساله كاستجابة
fs.readFile(path.join(__dirname, 'index.html'), (err, data) => {
if (err) {
// إذا حدث خطأ في قراءة الملف، أرسل رسالة خطأ 500
res.writeHead(500, { 'Content-Type': 'text/plain; charset=utf-8' });
res.end('خطأ داخلي في الخادم');
return;
}
// إرسال محتوى الملف كاستجابة
res.end(data);
});
});
// جعل الخادم يستمع للطلبات على المنفذ المحدد
server.listen(PORT, () => {
console.log(<code dir="ltr" style="background:#f3f4f6; color:#0056b3; padding:2px 6px; border-radius:4px; font-family:monospace; direction:ltr !important; display:inline-block;">الخادم يعمل على http://localhost:${PORT}</code>);
});
ملاحظة تقنية: استخدام path.join(__dirname, 'filename') يضمن أن مسار الملف صحيح بغض النظر عن مكان تشغيل السكربت، مما يجعله أكثر قوة.
الخطوة 3: توجيه المسارات (Routing) لعرض الصفحات المختلفة
الآن سنقوم بتعديل ملف index.js للتحقق من req.url (مسار الطلب) وتوجيه المستخدم إلى الصفحة الصحيحة.
قم بتحديث ملف index.js ليصبح كالتالي:
const http = require('http'); // استيراد وحدة HTTP لإنشاء خادم الويب
const fs = require('fs'); // استيراد وحدة File System لقراءة الملفات
const path = require('path'); // استيراد وحدة Path للتعامل مع مسارات الملفات
const PORT = 3000; // تحديد المنفذ الذي سيعمل عليه الخادم
// إنشاء الخادم
const server = http.createServer((req, res) => {
// تعيين رأس الاستجابة (Header) لـ HTML
res.writeHead(200, { 'Content-Type': 'text/html; charset=utf-8' });
// التحقق من مسار الطلب (req.url) لتوجيه المستخدم
if (req.url === '/') {
// إذا كان المسار هو '/' (الصفحة الرئيسية)، اقرأ index.html
fs.readFile(path.join(__dirname, 'index.html'), (err, data) => {
if (err) {
res.writeHead(500, { 'Content-Type': 'text/plain; charset=utf-8' });
res.end('خطأ داخلي في الخادم عند قراءة index.html');
return;
}
res.end(data);
});
} else if (req.url === '/about') {
// إذا كان المسار هو '/about'، اقرأ about.html
fs.readFile(path.join(__dirname, 'about.html'), (err, data) => {
if (err) {
res.writeHead(500, { 'Content-Type': 'text/plain; charset=utf-8' });
res.end('خطأ داخلي في الخادم عند قراءة about.html');
return;
}
res.end(data);
});
} else {
// إذا كان المسار غير معروف، أرسل صفحة خطأ 404
res.writeHead(404, { 'Content-Type': 'text/html; charset=utf-8' });
res.end('<h1>404 - الصفحة غير موجودة</h1><p>عذراً، المسار الذي طلبته غير موجود.</p>');
}
});
// جعل الخادم يستمع للطلبات على المنفذ المحدد
server.listen(PORT, () => {
console.log(<code dir="ltr" style="background:#f3f4f6; color:#0056b3; padding:2px 6px; border-radius:4px; font-family:monospace; direction:ltr !important; display:inline-block;">الخادم يعمل على http://localhost:${PORT}</code>);
});
ملاحظة تقنية: تستخدم الدالة res.end() لإرسال محتوى الاستجابة وإنهاء دورة الطلب-الاستجابة. يجب استدعاؤها بعد إرسال كل المحتوى.
الكود النهائي الكامل (index.js)
هذا هو الكود الكامل لملف الخادم بعد تطبيق جميع الخطوات:
const http = require('http');
const fs = require('fs');
const path = require('path');
const PORT = 3000;
const server = http.createServer((req, res) => {
res.writeHead(200, { 'Content-Type': 'text/html; charset=utf-8' });
if (req.url === '/') {
fs.readFile(path.join(__dirname, 'index.html'), (err, data) => {
if (err) {
res.writeHead(500, { 'Content-Type': 'text/plain; charset=utf-8' });
res.end('خطأ داخلي في الخادم عند قراءة index.html');
return;
}
res.end(data);
});
} else if (req.url === '/about') {
fs.readFile(path.join(__dirname, 'about.html'), (err, data) => {
if (err) {
res.writeHead(500, { 'Content-Type': 'text/plain; charset=utf-8' });
res.end('خطأ داخلي في الخادم عند قراءة about.html');
return;
}
res.end(data);
});
} else {
res.writeHead(404, { 'Content-Type': 'text/html; charset=utf-8' });
res.end('<h1>404 - الصفحة غير موجودة</h1><p>عذراً، المسار الذي طلبته غير موجود.</p>');
}
});
server.listen(PORT, () => {
console.log(<code dir="ltr" style="background:#f3f4f6; color:#0056b3; padding:2px 6px; border-radius:4px; font-family:monospace; direction:ltr !important; display:inline-block;">الخادم يعمل على http://localhost:${PORT}</code>);
});
النتيجة المتوقعة
بعد تشغيل الخادم باستخدام الأمر node index.js في سطر الأوامر:
- عند زيارة
http://localhost:3000/في متصفحك، ستظهر لك صفحةindex.html. - عند زيارة
http://localhost:3000/about، ستظهر لك صفحةabout.html. - عند زيارة أي مسار آخر، مثل
http://localhost:3000/contact، ستظهر لك صفحة الخطأ 404 التي قمنا بتعريفها. - يمكنك التنقل بين الصفحات باستخدام الروابط الموجودة داخل صفحات HTML.