وب و HTTP
زبان وب را با چشم خودت ببین: اجزای URL، درخواست و پاسخ HTTP خط به خط با curl -v، متدهای GET و POST و PUT و DELETE، کدهای وضعیت 2xx تا 5xx، هدرهای مهم (Host، Content-Type، Content-Length، Location)، ریدایرکت، فرستادن فرم و JSON، بیحالت بودن HTTP و کوکی، و تب Network مرورگر.
- حدود ۲۱ دقیقه مطالعه
- ۷ مثال اجراشده
- ۳ تمرین با جواب
- مقدماتی (از صفر مطلق)
- بهروزرسانی: ۲۹ مهر ۱۴۰۵
توی این درس یاد میگیری مرورگر و سرور وب دقیقاً چه چیزی به هم میگویند. HTTP پروتکل وب است و خبر خوب این است که متن ساده است: میتوانی خط به خطش را بخوانی. اجزای یک URL را میشناسی، با curl -v درخواست و پاسخ کامل را میبینی، متدها (GET، POST، …) و کدهای وضعیت (۲۰۰، ۳۰۱، ۴۰۴، ۵۰۰ و خانوادههایشان) را یاد میگیری، هدرهای مهم را میخوانی، یک فرم و یک JSON به سرور میفرستی و میفهمی سایتها با کوکی چطور «یادشان میماند» که تو کی هستی.
مسئله: «سایت خطا میدهد»
Section titled “مسئله: «سایت خطا میدهد»”وقتی کاربری میگوید «سایت کار نمیکند»، دهها مشکل متفاوت ممکن است پشتش باشد: صفحه پیدا نشده، دسترسی ندارد، سرور خراب شده، یا آدرس عوض شده. هر کدام از اینها در HTTP یک کد مشخص دارد و هر کدام سراغ یک نفر متفاوت را میگیرد. اگر HTTP را بخوانی، بهجای «کار نمیکند» میگویی «/api/orders با ۵۰۲ جواب میدهد، یعنی nginx سالم است ولی برنامهی پشتش جواب نمیدهد». این جمله نصف راه حل است.
تشبیه: فرم اداری
Section titled “تشبیه: فرم اداری”یک درخواست HTTP مثل فرم اداری است. بالای فرم نوشتهای چه کاری میخواهی و از کدام بخش («درخواست دریافت پروندهی شمارهی ۴۲»): این خط درخواست است. بعد چند خانهی مشخصات پر میکنی (اسم، تاریخ، زبان مورد نظر): اینها هدرند. و اگر لازم باشد، پیوست (یک فرم پرشده یا مدرک): این بدنه (body) است. جوابی که میگیری هم همین ساختار را دارد: یک مهر بالایش («انجام شد»، «پیدا نشد»، «به بخش دیگر مراجعه کنید»): کد وضعیت؛ چند خانه مشخصات؛ و خود پرونده.
URL: آدرس کامل یک چیز در وب
Section titled “URL: آدرس کامل یک چیز در وب”حرفهای غیرانگلیسی و نمادهای خاص در URL کدگذاری درصدی میشوند: «علی» در URL میشود %D8%B9%D9%84%DB%8C؛ یعنی همان شش بایت UTF-8 درس encoding، هر کدام با % و دو رقم هگز. برای همین وقتی لینک فارسی را کپی میکنی، گاهی شکل عجیبی دارد.
مثالهای عملی
Section titled “مثالهای عملی”همهی مثالها روی سرورهای خود کامپیوترت اجرا میشوند؛ اینترنت لازم نیست. در یک ترمینال سرور درس قبل را روشن کن و در ترمینال دیگر کار کن:
cd ~/site && python3 -m http.server 8000مثال ۱: یک درخواست و پاسخ کامل
Section titled “مثال ۱: یک درخواست و پاسخ کامل”curl -sv http://localhost:8000/notes.txt* Host localhost:8000 was resolved.* IPv6: ::1* IPv4: 127.0.0.1* Trying 127.0.0.1:8000...* Connected to localhost (127.0.0.1) port 8000> GET /notes.txt HTTP/1.1> Host: localhost:8000> User-Agent: curl/8.5.0> Accept: */*>* HTTP 1.0, assume close after body< HTTP/1.0 200 OK< Server: SimpleHTTP/0.6 Python/3.12.3< Date: Wed, 21 Oct 2026 20:57:16 GMT< Content-type: text/plain< Content-Length: 9< Last-Modified: Wed, 21 Oct 2026 20:54:07 GMT<* Closing connectionسلام-v (verbose) همهچیز را نشان میدهد. سه نوع خط داری:
*کارهایی که خود curl انجام داد: اسم را پیدا کرد (درس DNS؛ اینجا از/etc/hosts)، به127.0.0.1:8000وصل شد (درس پورت؛ دستدادن TCP).>چیزی که curl فرستاد: درخواست.<چیزی که سرور برگرداند: پاسخ. بعد از آن، خود محتوا (سلام).
درخواست را خط به خط بخوان:
| خط | معنی |
|---|---|
GET /notes.txt HTTP/1.1 |
متد (GET = بده)، مسیر، نسخهی پروتکل |
Host: localhost:8000 |
اسم سایتی که میخواهم؛ یک سرور با یک IP میتواند صدها سایت داشته باشد و با همین هدر میفهمد کدام |
User-Agent: curl/8.5.0 |
چه برنامهای درخواست داده (مرورگرها اسم و نسخهی خودشان را میگذارند) |
Accept: */* |
چه نوع پاسخی قبول دارم (*/* یعنی هر چیزی) |
| خط خالی | پایان هدرها |
و پاسخ:
| خط | معنی |
|---|---|
HTTP/1.0 200 OK |
خط وضعیت: نسخه، کد و توضیح کوتاه |
Server: SimpleHTTP/0.6 Python/3.12.3 |
نرمافزار سرور |
Date: ... GMT |
زمان سرور (همیشه به وقت گرینویچ) |
Content-type: text/plain |
نوع محتوا؛ مرورگر بر اساس این تصمیم میگیرد نشانش دهد، دانلودش کند یا اجرایش کند |
Content-Length: 9 |
اندازهی محتوا به بایت: «سلام» ۸ بایت (درس encoding) + یک خط جدید |
| خط خالی | پایان هدرها، بعد بدنه |
همهاش متن است. مرورگر هم برای هر صفحه دقیقاً همین را میفرستد (با هدرهای بیشتر). (HTTP/1.0 در پاسخ به این دلیل است که سرور سادهی پایتون نسخهی قدیمی را حرف میزند؛ سرورهای واقعی HTTP/1.1 یا HTTP/2 جواب میدهند.)
مثال ۲: فقط هدرها، و ریدایرکت
Section titled “مثال ۲: فقط هدرها، و ریدایرکت”curl -sI http://localhost:8000/imagesHTTP/1.0 301 Moved PermanentlyServer: SimpleHTTP/0.6 Python/3.12.3Date: Wed, 21 Oct 2026 20:57:16 GMTLocation: /images/Content-Length: 0-I فقط هدرها را میگیرد (با متد HEAD). سرور گفت 301: «این آدرس جابهجا شده، برو به آدرسی که در Location نوشتهام» (/images/ با اسلش آخر، چون پوشه است). مرورگر این را خودکار دنبال میکند و تو اصلاً متوجه نمیشوی. curl نه، مگر اینکه -L بدهی:
curl -sL -o /dev/null -w "%{http_code} %{url_effective} redirects=%{num_redirects}\n" http://localhost:8000/images200 http://localhost:8000/images/ redirects=1با -L، curl یک ریدایرکت را دنبال کرد و به ۲۰۰ رسید. ریدایرکت همهجا هست: از http:// به https://، از example.com به www.example.com، از آدرس قدیمی یک مقاله به آدرس جدید، و بعد از ورود موفق به صفحهی اصلی.
مثال ۳: کدهای وضعیت
Section titled “مثال ۳: کدهای وضعیت”کد سهرقمی است و رقم اول خانوادهاش را میگوید. فقط با رقم اول نصف تشخیص را انجام دادهای:
| خانواده | معنی | کدهای رایج | تقصیر کیست؟ |
|---|---|---|---|
| 2xx | موفق | 200 OK، 201 Created، 204 No Content |
هیچکس |
| 3xx | برو جای دیگر | 301 (دائمی)، 302 (موقت)، 304 Not Modified (از کش خودت استفاده کن) |
هیچکس، معمولاً |
| 4xx | درخواست تو مشکل دارد | 400 Bad Request، 401 (وارد نشدهای)، 403 Forbidden (اجازه نداری)، 404 Not Found، 405، 429 Too Many Requests |
کلاینت |
| 5xx | سرور مشکل دارد | 500 Internal Server Error، 501 Not Implemented، 502 Bad Gateway، 503 Service Unavailable، 504 Gateway Timeout |
سرور |
سرور سادهی پایتون فقط خواندن را بلد است. ببین به متدهای دیگر چه میگوید:
curl -s -o /dev/null -w "%{http_code}\n" -X POST -d "name=ali" http://localhost:8000/curl -s -o /dev/null -w "%{http_code}\n" -X DELETE http://localhost:8000/notes.txt501501-X متد را تعیین میکند. 501 Not Implemented: «این متد را پیاده نکردهام» (سرورهای دیگر برای همین حالت 405 Method Not Allowed میدهند). لاگ سرور هم همین را ثبت کرد:
127.0.0.1 - - [22/Oct/2026 00:27:16] code 501, message Unsupported method ('POST')127.0.0.1 - - [22/Oct/2026 00:27:16] "POST / HTTP/1.1" 501 -127.0.0.1 - - [22/Oct/2026 00:27:16] code 501, message Unsupported method ('DELETE')127.0.0.1 - - [22/Oct/2026 00:27:16] "DELETE /notes.txt HTTP/1.1" 501 -کاربری میگوید سایت «خطای 403» میدهد. مشکل احتمالاً کجاست؟
جواب درست: درخواست به سرور رسیده ولی اجازهی دیدن این صفحه را ندارد (دسترسی/مجوز)
4xx سمت درخواست است؛ 403 یعنی «شناختمت ولی اجازه نداری» (یا مجوز فایل روی سرور درست نیست).
مثال ۴: متدها، فعلهای HTTP
Section titled “مثال ۴: متدها، فعلهای HTTP”| متد | معنی | مثال |
|---|---|---|
GET |
بده (فقط خواندن؛ نباید چیزی را عوض کند) | باز کردن صفحه، جستوجو |
POST |
این را بگیر و کاری کن (ساختن چیز جدید) | ثبت سفارش، ارسال فرم |
PUT / PATCH |
این را جایگزین / بخشیاش را عوض کن | ویرایش پروفایل |
DELETE |
حذف کن | حذف یک کالا از سبد |
HEAD |
مثل GET ولی فقط هدرها | curl -I |
قانون مهم: GET نباید چیزی را تغییر دهد. مرورگرها، موتورهای جستوجو و کشها آزادانه درخواستهای GET را تکرار یا از قبل اجرا میکنند. لینکی مثل /delete?id=5 که با GET کار میکند، یک روز توسط رباتی که فقط لینکها را دنبال میکند «کلیک» میشود.
مثال ۵: فرستادن داده، فرم و JSON
Section titled “مثال ۵: فرستادن داده، فرم و JSON”برای دیدن دقیقاً چیزی که فرستاده میشود، از nc درس پورت بهجای سرور استفاده کن: هر چه برسد را چاپ میکند. در ترمینال سرور (اول http.server را با Ctrl+C ببند):
nc -l -N 127.0.0.1 9000و در ترمینال دیگر یک فرم بفرست، همان کاری که دکمهی «ثبت» در یک صفحهی وب میکند:
curl -s -m 1 -X POST -d "name=علی&qty=2" "http://127.0.0.1:9000/order?ref=insta"POST /order?ref=insta HTTP/1.1Host: 127.0.0.1:9000User-Agent: curl/8.5.0Accept: */*Content-Length: 17Content-Type: application/x-www-form-urlencoded
name=علی&qty=2(-m 1 یعنی بعد از یک ثانیه منتظر جواب نمان؛ nc جوابی نمیدهد.) دو جا داده فرستاده شد: query در خود آدرس (?ref=insta، معمولاً برای فیلتر و جستوجو) و بدنه بعد از خط خالی (برای دادهی اصلی). Content-Length: 17 بایت است، نه حرف: «علی» ۶ بایت دارد. Content-Type به سرور میگوید بدنه را چطور بخواند: x-www-form-urlencoded همان قالب فرمهای HTML است (کلید=مقدار&کلید=مقدار). مرورگر حرفهای فارسی را در این قالب کدگذاری درصدی هم میکند؛ curl فقط وقتی بخواهی (--data-urlencode "name=علی" میفرستد name=%D8%B9%D9%84%DB%8C).
برنامهها و اپها بیشتر JSON میفرستند (قالب دادهای که در دورهی پایتون مفصل میبینی). دوباره nc -l -N 127.0.0.1 9000 و:
curl -s -m 1 -H "Content-Type: application/json" -d '{"sku": "NW-SW", "qty": 1}' http://127.0.0.1:9000/api/ordersPOST /api/orders HTTP/1.1Host: 127.0.0.1:9000User-Agent: curl/8.5.0Accept: */*Content-Type: application/jsonContent-Length: 26
{"sku": "NW-SW", "qty": 1}-H یک هدر اضافه میکند. به اینجور آدرسها که برنامهها (نه آدمها) با JSON با آنها حرف میزنند API میگویند. اپ موبایل فروشگاه با همین شکل درخواستها با سرور حرف میزند.
مثال ۶: HTTP یادش نمیماند، کوکی یادش میاندازد
Section titled “مثال ۶: HTTP یادش نمیماند، کوکی یادش میاندازد”HTTP بیحالت (stateless) است: هر درخواست مستقل است و سرور از درخواست قبلی تو چیزی نمیداند. پس چطور سایت میداند وارد شدهای یا سبد خریدت چه دارد؟ با کوکی: سرور در پاسخ یک هدر Set-Cookie میفرستد، مرورگر آن را نگه میدارد و در هر درخواست بعدی به همان سایت در هدر Cookie برمیگرداند. یک سرور کوچک که با کوکی بازدیدهای هر نفر را جدا میشمارد، ~/cookie_server.py:
from http.server import BaseHTTPRequestHandler, HTTPServerfrom http.cookies import SimpleCookie
class Counter(BaseHTTPRequestHandler): def do_GET(self): cookie = SimpleCookie(self.headers.get("Cookie", "")) visits = int(cookie["visits"].value) + 1 if "visits" in cookie else 1 body = f"این بازدید شمارهی {visits} توست.\n" self.send_response(200) self.send_header("Content-Type", "text/plain; charset=utf-8") self.send_header("Set-Cookie", f"visits={visits}; Max-Age=3600") self.end_headers() self.wfile.write(body.encode("utf-8"))
HTTPServer(("127.0.0.1", 8002), Counter).serve_forever()python3 ~/cookie_server.pyدر ترمینال دیگر:
curl -s -i http://127.0.0.1:8002/HTTP/1.0 200 OKServer: BaseHTTP/0.6 Python/3.12.3Date: Wed, 21 Oct 2026 20:57:30 GMTContent-Type: text/plain; charset=utf-8Set-Cookie: visits=1; Max-Age=3600
این بازدید شمارهی 1 توست.(-i هدرهای پاسخ را هم چاپ میکند.) سرور گفت «این را نگه دار: visits=1، برای یک ساعت». curl بهطور پیشفرض کوکی نگه نمیدارد، پس هر بار «بازدید ۱» است:
curl -s http://127.0.0.1:8002/curl -s http://127.0.0.1:8002/این بازدید شمارهی 1 توست.این بازدید شمارهی 1 توست.با -c (کوکیها را در فایل ذخیره کن) و -b (از فایل بفرست)، curl مثل مرورگر رفتار میکند:
curl -s -c jar.txt -b jar.txt http://127.0.0.1:8002/curl -s -c jar.txt -b jar.txt http://127.0.0.1:8002/curl -s -c jar.txt -b jar.txt http://127.0.0.1:8002/این بازدید شمارهی 1 توست.این بازدید شمارهی 2 توست.این بازدید شمارهی 3 توست.حالا سرور تو را «میشناسد»، فقط به این دلیل که خودت هر بار گفتی کی هستی. و این یعنی میتوانی دروغ هم بگویی:
curl -s -H "Cookie: visits=999" http://127.0.0.1:8002/این بازدید شمارهی 1000 توست.کوکی در دست کلاینت است و کاربر میتواند عوضش کند (همان قانون درس قبل: به کلاینت اعتماد نکن). برای همین سایتهای واقعی در کوکی چیزی مثل «من مدیرم» یا «اعتبارم ۱ میلیون» نمیگذارند؛ فقط یک شناسهی تصادفی و طولانی جلسه (session ID) میگذارند و اطلاعات واقعی را روی سرور، کنار همان شناسه، نگه میدارند. اگر کسی شناسهی جلسهی تو را بدزدد، خود تو میشود؛ یکی از دلیلهای اصلی HTTPS (درس بعد) همین است.
مثال ۷: همینها در مرورگر
Section titled “مثال ۷: همینها در مرورگر”در مرورگر (Chrome، Firefox، Edge) کلید F12 را بزن (یا راستکلیک ← Inspect) و برو به تب Network. صفحهای را باز کن (یا http://localhost:8000 را رفرش کن). هر ردیف یک درخواست HTTP است: مسیر، متد، کد وضعیت، نوع و اندازه. روی یکی کلیک کن: همان هدرهای درخواست و پاسخ مثال ۱ را میبینی. یک صفحهی خبری معمولی صد تا دویست درخواست دارد: HTML، فایلهای CSS و جاوااسکریپت، عکسها، فونتها و APIها. وقتی صفحه کند است یا جایی از آن خالی میماند، این تب اولین جایی است که نگاه میکنی: ردیفهای قرمز (۴xx، ۵xx) و ردیفهایی که زمان زیادی گرفتهاند.
پشت پرده: از HTTP/1.1 تا HTTP/3
Section titled “پشت پرده: از HTTP/1.1 تا HTTP/3”- HTTP/1.1 (۱۹۹۷): متن خوانا، همان چیزی که در این درس دیدی. روی یک اتصال، درخواستها یکییکی و به نوبت.
- HTTP/2 (۲۰۱۵): همان مفهومها (متد، هدر، کد)، ولی دودویی و فشرده، و دهها درخواست همزمان روی یک اتصال. برای همین در
curl -vیک سایت واقعی ممکن استHTTP/2 200ببینی. - HTTP/3 (۲۰۲۲): همان، روی UDP (با پروتکل QUIC) بهجای TCP، برای شروع سریعتر و کار بهتر روی شبکههای موبایل ناپایدار. (یادت هست
/etc/servicesبرای ۴۴۳ هر دوtcpوudpداشت؟)
خبر خوب: معنی متدها، کدها و هدرها در هر سه یکی است. چیزی که اینجا یاد گرفتی، همهجا کار میکند.
جدولهای مرجع
Section titled “جدولهای مرجع”| هدر | کجا | معنی |
|---|---|---|
Host |
درخواست | اسم سایت |
User-Agent |
درخواست | نرمافزار کلاینت |
Content-Type |
هر دو | نوع بدنه (text/html، application/json، …) |
Content-Length |
هر دو | اندازهی بدنه به بایت |
Location |
پاسخ | آدرس مقصد ریدایرکت (با ۳xx) |
Set-Cookie / Cookie |
پاسخ / درخواست | گذاشتن و برگرداندن کوکی |
Cache-Control |
پاسخ | تا کی میشود این را کش کرد |
Authorization |
درخواست | مدرک ورود (توکن) برای APIها |
| گزینهی curl | کار |
|---|---|
-v |
نمایش درخواست و پاسخ کامل |
-I |
فقط هدرها (HEAD) |
-i |
هدرهای پاسخ + بدنه |
-L |
دنبال کردن ریدایرکت |
-X POST |
تعیین متد |
-d "k=v" |
فرستادن بدنه (فرم) |
-H "Name: value" |
اضافه کردن هدر |
-c file -b file |
ذخیره و فرستادن کوکی |
-s -o /dev/null -w "%{http_code}\n" |
فقط کد وضعیت |
اشتباهات رایج
Section titled “اشتباهات رایج”۱) نگاه نکردن به کد وضعیت
Section titled “۱) نگاه نکردن به کد وضعیت”«صفحه سفید است» ممکن است ۲۰۰ با محتوای خالی باشد، یا ۵۰۰. راهحل: اول کد را ببین (curl -I، تب Network)؛ رقم اول مسیر را تعیین میکند.
۲) دنبال نکردن ریدایرکت
Section titled “۲) دنبال نکردن ریدایرکت”curl بدون -L فقط ۳۰۱ را نشان میدهد و برنامهای که ریدایرکت را دنبال نکند، صفحهی خالی میبیند (سناریو). راهحل: -L در curl و بررسی هدر Location.
۳) فراموش کردن Content-Type
Section titled “۳) فراموش کردن Content-Type”JSON بدون -H "Content-Type: application/json" فرستاده میشود و سرور آن را فرم فرض میکند و نمیفهمد (معمولاً ۴۰۰ یا ۴۱۵). راهحل: همیشه نوع بدنه را بگو.
۴) تغییر داده با GET
Section titled “۴) تغییر داده با GET”لینکهای ?action=delete را رباتها و پیشبارگذاری مرورگر «کلیک» میکنند. راهحل: هر تغییری با POST، PUT یا DELETE.
۵) اطلاعات مهم در کوکی یا query
Section titled “۵) اطلاعات مهم در کوکی یا query”قیمت، نقش کاربر یا رمز در کوکی یا URL قابلدیدن و تغییر است (و URLها در لاگها و تاریخچه میمانند). راهحل: فقط شناسهی تصادفی در کوکی؛ دادهی واقعی روی سرور؛ و همه روی HTTPS.
با curl و سرور http.server در ~/site، کد وضعیت اینها را بگیر و برای هر کدام بگو یعنی چه: /، /notes.txt، /missing.png، /images (بدون اسلش آخر).
دیدن جواب
for p in / /notes.txt /missing.png /images; do curl -s -o /dev/null -w "$p -> %{http_code}\n" "http://localhost:8000$p"done/ -> 200/notes.txt -> 200/missing.png -> 404/images -> 301۲۰۰ موفق (برای / سرور خودکار index.html را داد)، ۴۰۴ چنین فایلی نیست، ۳۰۱ ریدایرکت به /images/. ($p در حلقهی bash هر بار یکی از مسیرهاست.)
URL زیر را تکهتکه کن و بگو هر تکه به کدام لایه یا برنامه میرسد: http://localhost:8000/products/search?q=کتاب&page=2#top. بعد با nc -l -N 127.0.0.1 8000 (بهجای سرور) و curl ببین کدام بخشها واقعاً به سرور فرستاده میشوند.
دیدن جواب
nc -l -N 127.0.0.1 8000 # ترمینال ۱curl -s -m 1 "http://localhost:8000/products/search?q=کتاب&page=2#top" # ترمینال ۲GET /products/search?q=کتاب&page=2 HTTP/1.1Host: localhost:8000User-Agent: curl/8.5.0Accept: */*http: پروتکل؛ curl بر اساس آن تصمیم گرفت رمزنگاری نکند و پورت پیشفرض ۸۰ باشد.localhost: برای DNS/hosts و در هدرHost.8000: پورت TCP./products/search?q=کتاب&page=2: مسیر و query که در خط درخواست به سرور رسید.#top: نرسید. fragment فقط برای مرورگر است («به بخش top صفحه اسکرول کن»).
(مرورگر «کتاب» را قبل از فرستادن به %DA%A9%D8%AA%D8%A7%D8%A8 تبدیل میکرد؛ curl آن را همانطور خام فرستاد.)
با curl یک «جلسه»ی کامل با cookie_server.py شبیهسازی کن: سه بازدید با یک فایل کوکی (a.txt) و دو بازدید با فایل کوکی دیگر (b.txt). نشان بده سرور دو «کاربر» جدا میبیند. بعد محتوای a.txt را نگاه کن و بگو چرا این طراحی شمارنده ناامن است و طراحی درست چه شکلی است.
دیدن جواب
rm -f a.txt b.txtfor i in 1 2 3; do curl -s -c a.txt -b a.txt http://127.0.0.1:8002/; donefor i in 1 2; do curl -s -c b.txt -b b.txt http://127.0.0.1:8002/; donetail -1 a.txtاین بازدید شمارهی 1 توست.این بازدید شمارهی 2 توست.این بازدید شمارهی 3 توست.این بازدید شمارهی 1 توست.این بازدید شمارهی 2 توست.127.0.0.1 FALSE / FALSE 1792619850 visits 3دو فایل کوکی مثل دو مرورگر جدا (یا دو آدم) هستند. خط آخر فایل: سایت، مسیر، زمان انقضا (عدد ثانیه از ۱۹۷۰) و خود کوکی visits=3. ناامن است چون مقدار واقعی در دست کلاینت است و میشود عوضش کرد (مثال ۶، visits=999). اگر این عدد «امتیاز» یا «اعتبار» بود، کاربر به خودش هر چقدر بخواهد امتیاز میداد. طراحی درست: سرور یک شناسهی تصادفی و غیرقابلحدس (مثلاً ۳۲ کاراکتر) در کوکی میگذارد (session=k8Zq...) و عدد بازدید را روی سرور (در حافظه یا دیتابیس) کنار همان شناسه نگه میدارد. کلاینت فقط یک «شمارهی کمد» دارد، نه خود کمد.
آزمونک
Section titled “آزمونک”در خط «GET /notes.txt HTTP/1.1»، /notes.txt چیست؟
جواب درست: مسیر (path) چیزی که روی سرور میخواهی
متد GET و نسخه HTTP/1.1 است.
کد 404 به کدام خانواده تعلق دارد و یعنی چه؟
جواب درست: 4xx؛ چیزی که خواستی پیدا نشد
4xx یعنی مشکل در درخواست.
پاسخ 301 با هدر Location: https://... یعنی…
جواب درست: آدرس جابهجا شده؛ به آدرس Location برو
مرورگر خودکار دنبال میکند؛ curl با -L.
کدام بخش URL هرگز به سرور فرستاده نمیشود؟
جواب درست: fragment (#...)
fragment فقط برای مرورگر است.
HTTP «بیحالت» است یعنی…
جواب درست: هر درخواست مستقل است و سرور خودبهخود درخواست قبلی را به یاد نمیآورد
کوکی راه یادآوری است.
چرا نباید «نقش: مدیر» را مستقیم در کوکی گذاشت؟
جواب درست: کوکی در دست کلاینت است و کاربر میتواند آن را عوض کند
فقط شناسهی تصادفی جلسه؛ داده روی سرور.
جمعبندی
Section titled “جمعبندی”- HTTP متن است: درخواست (متد، مسیر، هدرها، بدنه) و پاسخ (کد وضعیت، هدرها، بدنه)، با یک خط خالی بین هدر و بدنه.
- URL: scheme، host، port، path، query و fragment (که به سرور نمیرسد).
- کدها با رقم اول: 2xx موفق، 3xx برو جای دیگر، 4xx تقصیر درخواست، 5xx تقصیر سرور.
- متدها: GET بخوان (بدون تغییر)، POST بساز، PUT/PATCH عوض کن، DELETE حذف کن.
- HTTP بیحالت است؛ کوکی (
Set-Cookie،Cookie) سرور را «یادآور» میکند، ولی در دست کلاینت است. curl -vو تب Network مرورگر، دو ابزار اصلی دیدن HTTP.
| دستور | کاری که میکند |
|---|---|
curl -v URL | درخواست و پاسخ کامل |
curl -I URL | فقط هدرها |
curl -L URL | دنبال کردن ریدایرکت |
curl -s -o /dev/null -w "%{http_code}\n" URL | فقط کد وضعیت |
curl -X POST -d "a=1" URL | فرستادن فرم |
curl -H 'Content-Type: application/json' -d '{...}' URL | فرستادن JSON |
curl -c jar -b jar URL | نگه داشتن کوکی |
F12 → Network | دیدن درخواستها در مرورگر |