اولین سرور محلی با node:http و آزمایش در PowerShell
در این درس ۵ بخش
در این درس یک سرور کوچک میسازیم تا چرخهٔ کامل درخواست و پاسخ را لمس کنید. وابستگی شخص ثالث نصب نمیشود و پایگاه داده نداریم. دو نشانی برای خواندن داده تعریف میکنیم: /health برای وضعیت سادهٔ نمونه و /greeting برای یک پیام ثابت. برنامه فقط روی حلقهٔ محلی رایانه گوش میدهد. بازکردن پورت عمومی، تغییر فایروال یا اجرای ترمینال با دسترسی مدیر برای این تمرین لازم نیست. هدف، تسلط بر رفتار پایه است، نه میزبانی عمومی برنامه.
ساخت فایل و اجرای سرور
در VS Code یک پوشهٔ مستقل با نام first-http باز کنید و فایل server.mjs را با کد زیر بسازید. اگر در درس قبلی سرور دیگری روی پورت ۳۱۰۰ روشن مانده است، ابتدا در همان ترمینال با Ctrl+C آن را متوقف کنید. پسوند mjs باعث میشود import بهعنوان ماژول ES تفسیر شود. نام ماژول node:http بخشی از Node.js است؛ آن را با npm نصب نکنید.
import { createServer } from 'node:http';
function sendJson(res, status, value, extraHeaders = {}) {
res.writeHead(status, {
'content-type': 'application/json; charset=utf-8',
'cache-control': 'no-store',
...extraHeaders
});
res.end(JSON.stringify(value));
}
const server = createServer((req, res) => {
const url = new URL(req.url ?? '/', 'http://127.0.0.1:3100');
if (req.method !== 'GET') {
sendJson(res, 405, { error: 'method_not_allowed' }, { allow: 'GET' });
return;
}
if (url.pathname === '/health') {
sendJson(res, 200, { status: 'ok', service: 'first-http' });
return;
}
if (url.pathname === '/greeting') {
sendJson(res, 200, { message: 'سلام از سرور محلی' });
return;
}
sendJson(res, 404, { error: 'not_found' });
});
server.on('error', error => {
console.error('Server could not start:', error.code);
process.exitCode = 1;
});
server.listen(3100, '127.0.0.1', () => {
console.log('Open http://127.0.0.1:3100/health');
});node .\server.mjsپس از دیدن پیام Open، ترمینال را باز نگه دارید. در مرورگر همان نشانی /health را باز کنید؛ باید شیء JSON با status برابر ok ببینید. ظاهر این پاسخ شبیه یک وبسایت طراحیشده نیست و اشکالی ندارد: API برای تحویل داده است. اگر مرورگر برای favicon درخواست جدا بفرستد، پاسخ ۴۰۴ آن مسیر به معنی خرابشدن /health نیست. هر درخواست را با مسیر و وضعیت خودش بررسی کنید.
هر پاسخ باید یک بار تمام شود
تابع sendJson وضعیت و هدرها را تعیین میکند و با end پاسخ را پایان میدهد. returnهای پس از پاسخ، مانع افتادن همان درخواست به شاخههای بعدی میشوند. اگر یک پاسخ را پایان دهید و دوباره بخواهید هدر یا داده بفرستید، خطاهای مربوط به پاسخ تمامشده خواهید دید. در عوض اگر end فراموش شود، کلاینت ممکن است همچنان منتظر بماند. مسیر اجرای هر شاخه را با انگشت دنبال کنید و نقطهٔ پایان را مشخص کنید.
از pathname استفاده میکنیم تا بخش جستوجو با مسیر اشتباه نشود؛ /health?check=1 همچنان مسیر /health دارد. پایهٔ URL در کد مقدار ثابت محلی است و از Host دریافتشده برای تصمیم امنیتی استفاده نمیکنیم. این سرور عمداً مسیر فایل، اجرای دستور یا ذخیرهٔ داده ندارد. پس نمیتوان آن را با افزودن یک خط به سامانهٔ بارگذاری فایل یا فروشگاه واقعی تبدیل کرد. در درس امنیت، قرارداد ورودی را جدا بررسی میکنیم.
ترمینال دوم؛ تبدیل پاسخ به داده
در VS Code از Terminal → New Terminal یک PowerShell دوم باز کنید. دستور زیر به ابزار داخلی PowerShell متکی است و نصب Postman برای آن لازم نیست. Invoke-RestMethod پاسخ JSON را به دادهٔ قابل دسترسی تبدیل میکند؛ برای دیدن هدر خام و وضعیت HTTP از curl.exe در مثال بعد استفاده میکنیم.
$result = Invoke-RestMethod -Uri "http://127.0.0.1:3100/health"
$result.status
curl.exe -i "http://127.0.0.1:3100/missing"
curl.exe -i -X POST "http://127.0.0.1:3100/health"دستور اول مقدار ok میدهد. درخواست missing باید وضعیت ۴۰۴ و error برابر not_found داشته باشد. POST به نمونهٔ ما ۴۰۵ همراه هدر Allow: GET میگیرد. نوشتن curl.exe عمدی است؛ در برخی محیطهای PowerShell نام کوتاه curl ممکن است نام مستعار ابزار دیگری باشد. اگر curl.exe در دستگاه شما موجود نیست، دستور اول برای آزمایش موفق کافی است؛ نصب ابزار نامطمئن یا تغییر تنظیمات امنیتی لازم نیست.
عیبیابی کوتاه و قابل تکرار
اگر پیام شروع را نمیبینید، نخست خروجی ترمینال سرور را بخوانید. EADDRINUSE یعنی آن نشانی و پورت در دسترس این نمونه نیست؛ اجرای نسخهٔ دوم روی پورت یکسان، علت معمول تمرین است. اگر نام فایل پیدا نشد، محل ترمینال و نام واقعی server.mjs را بررسی کنید. اگر مرورگر وصل نمیشود ولی سرور ظاهراً روشن است، نشانی، پورت و http بودن را دقیق مقایسه کنید؛ https را به این سرور آموزشی اضافه نکنید. در درس بعد، این نشانهها را منظمتر بررسی میکنیم.
تمرین و پاسخ تشریحی
مسیر GET /about را اضافه کنید تا {"course":"node-windows","localOnly":true} برگرداند. سه آزمون دستی بنویسید: مسیر درست، مسیر ناشناخته و روش POST. پاسخ راهنما: یک شرط pathname پیش از پاسخ ۴۰۴ اضافه کنید، sendJson با ۲۰۰ را صدا بزنید و return بگذارید. پاسخها باید بهترتیب ۲۰۰، ۴۰۴ و ۴۰۵ باشند. در پایان Ctrl+C بزنید و درخواست موفق قبلی را دوباره امتحان کنید؛ اکنون شکست ارتباط را از پاسخ ناموفق HTTP تشخیص دهید.
معیار تحویل، فایل قابل اجرا، نشانی دقیق، خروجی سه آزمون و توضیح محل پایان پاسخ است. تغییر پیام بدون درک return کافی نیست. پروژهٔ نهایی دوره بعداً ذخیرهٔ موقت کارها، اعتبارسنجی و آزمون خودکار را اضافه میکند؛ این درس فقط پایهٔ سرور را با کمترین ابزار لازم روشن میکند. اگر خطا دارید، خروجی مربوط و دستور اجرا را نگه دارید و پیش از نصب بستهٔ تازه، همان ورودی را دوباره بررسی کنید.
Node.js، مرجع HTTP: https://nodejs.org/api/http.html
Microsoft، Invoke-RestMethod: https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.utility/invoke-restmethod
curl، نسخهٔ همراه ویندوز: https://curl.se/windows/microsoft.html
تألیف و کد اختصاصی: تحریریه درسآوند.
متن درسهای عمومی را بدون ورود بخوانید.