aminda
aminda
خواندن ۱۲ دقیقه·۳ سال پیش

آشنایی با HTTP و Server ها (بخش اول)

پیشنهاد می کنم ابتدا مقدمه این سری از مقالات رو بخونید تا پیش زمینه خوبی داشته باشین برای شروع لینک

زبان مرورگرها چیست ؟ ?

مرورگرها برای درخواست اطلاعات فقط به یک زبان صحبت می کنند که نام آن زبان HTTP هستش، می توان اون را قانون یا پروتوکل رد و بد اطلاعات برای مرورگرها نیز نامید .

HTTP = Hyper Text Transfer Protocol

که معنی آن به فارسی تقریبا میشه : قانون جابه جایی ابر متن .

ابر متن هم متن هایی هستند که میتونن خیلی بزرگ باشند و اونها رو روی دستگاه های الکترونیکی می بینیم . توضیحات بیشتر

همچنین باید به این نکته هم اشاره کرد که مروگر ها وقتی از پروتوکل HTTP استفاده میکنن بایست به سروری وصل بشن که اون سرور هم قابلیت پاسخ گویی به درخواست های HTTP رو داشته باشه.

شبکه HTTP

برای رد و بدل اطلاعات نیاز به شبکه داریم ، و شبکه های کامپیوتری در سطح نرم افزار بر اساس یک مفهوم انتزاعی (ذهنی) به نام سوکت برقرار می شوند و سوکت ها نشان دهنده یک اتصال باز ( به صورت ویژه ) به رایانه دیگری هستند .

کار سرور گوش دادن به اتصال های درخواستی است و کار کلاینت باز کردن یک اتصال می باشد.

اتصالاها بوسیله IP ، یعنی آدرس ها که به صورت عددی هستند ایجاد می شوند . IP آدرس نشانی دقیق سرور مد نظر ما در اینترنت هستش که میتونه شامل یک شماره پورت هم باشه ،که بعد از آدرس IP با دونقطه قرار می گیره.

مانند :

192.168.0.255:443

که عدد 443 شماره پورت مورد نظر است که این شماره پورت نوع سرویس درخواستی از سرور را مشخص میکند.

هر قسمت IP آدرس که با نقطه از هم جدا شده است میتواند عددی مابین 0 تا 255 باشد و شماره پورت میتواند عددی مابین 0 تا 65535 باشد

میتونیم اینجوری فکر کنیم که IP مانند آدرس رسیدن به یک آپارتمان هستش ( آپارتمان سرور مورد نظر ما هستش که میخواهیم به آن وصل بشیم که شامل اتاق های زیادی هست. ) و شماره پورت اتاق خاص مدنظر ما در این آپارتمان هستش که میخواهیم وارد آن بشیم و با آن رد و بدل اطلاعات را انجام بدهیم.

داده هایی که در یک اتصال سوکت رد و بدل میشوند همگی از نوع بایت هستند (bytes) ، که میتوانند text یا binary باشند .

پس HTTPS چیه ؟

پروتوکل HTTP ساده یک پروتکل رمزگذاری نشده هستش. اما برای امنیت بهتر است که از پروتوکل HTTPS استفاده کنیم که یک پروتوکل رمز گذاری شده بوسیله ssl هستش .

شماره پورت دیفالت در IP آدرس :

پروتوکل های HTTP و HTTPS در حالت اولیه یا دیفالت خودشان در ارتباط با سرور از شماره پورت های خاصی استفاده میکنند. پروتوکل HTTP از شماره پورت 80 و پروتوکل HTTPS از شماره پورت 443 در ارتباطات استفاده میکنند. مثلا آدرس URL به صورت زیر

http://192.168.0.255

اشاره میکند که پورت ما 80 است و اگر همین درخواست با پروتوکل HTTPS ارسال بشه دلالت میکنه که پورت ما به صورت دیفالت 443 هستش.سایر پورت ها نیز اغلب بسته به تنظیمات پروژه استفاده می شوند ،به عنوان مثال، بسیاری از برنامه ها در یک محیط توسعه به پورت 8080 یا 3000 گوش می دهند ( اگر از ری اکت استفاده کرده باشین ، یا در آینده آستفاده کنید این پورت رو میبنیدش . که در زمان توسعه اپلیکیشن ، برنامه شما روی این پورت به صورت دیفالت قابل دسترس هستش .)

اما استفاده از این شماره ها و به خاطر سپردن اونها کاره خیلی سختی هستش برای ما ?

حالا DNS وارد می شود

به خاطر همین ما آدرس ها رو به صورت یک متن مینویسیم و کار تبدیل کردن اونها به عدد ها رو به چیزی به نام DNS میسپاریم ، معمولا در مقالات و توضیحات DNS رو به عنوان یک دفترچه تلفن معرفی میکنن که میدونه هر اسم سایتی دقیقا به چه سروری اشاره میکنه ، خود DNS یک سرور در اینترنت هستش که وقتی که اسم سایت رو در مرورگر وارد میکنیم مرورگر اسم سایت رو به اون میفرسته و سپس DNS آدرس IP اون سرور رو به مرورگر برمیگردونه و سپس مرورگر بوسیله این IP آدرس به سرور متصل میشود

درخواست و پاسخ HTTP

همانطور که قبلا اشاره شد HTTP مخفف HyperText Transfer Protocol یعنی پروتکل جابه جایی ابر متن هستش ، این متنی که بوسیله HTTP جابه جا میشه و و نقل و انتقال پیدا میکنه یک متن ساده بدون حالت یا stateless هستش. برای بدون حالت ( وضعیت ) بودن اون میشه این تعریف رو در نظر گرفت که به عنوان یک پروتکل بدون حالت نامیده می شه زیرا هر درخواست به طور مستقل و بدون اطلاع از درخواست هایی که قبل از آن اجرا شده است اجرا می شود. یا این تعریف رو در نظر داشته باشید : به این معنی که هر بار کلاینت یک صفحه وب را درخواست می کند، مرورگر کاربر یک اتصال جداگانه به سرور باز می کند و سرور به طور خودکار هیچ سابقه ای از درخواست قبلی را نگه نمی داره .

و در حالت کلی HTTP یک پروتوکل بر پایه درخواست ها و پاسخ ها هستش :

1- در ابتدا یک کلاینت باید یک اتصال به سرور را ارسال کند و درخواستی را با استفاده از یک قالب متنی بفرستد .

2- سپس سرور درخواست را تجزیه و تحلیل می کند، و با توجه به درخواست ارسال شده کدی را برای پردازش و رسیدگی مناسب به درخواست اجرا می کند و یک پاسخ مبتنی بر متن را سمت کلاینت ارسال می کندو پس از ارسال پاسخ، اتصال سوکت باز را می بندد

3- هر درخواست / پاسخ یک تراکنش مستقل بین کلاینت و سرور است و به طور پیش‌فرض هیچ ارتباطی بین درخواست‌های جداگانه وجود ندارد.

البته هم درخواست ها و هم پاسخ ها ممکن است حاوی داده های باینری باشند، اما محتوای درخواست و پاسخ مربوط به HTTP دستورالعمل های متنی هستند.

یک نمونه درخواست HTTP معمولی که مروگر ( کلاینت ما ) به سمت سرور میفرسته به شکل زیر میتونه باشه:

GET <https://www.example.com/description.html> HTTP/1.1 Host: www.example.com User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) Chrome/16.0.912.75 Safari/535.7 Accept: text/html,application/xhtml+xml Referer: <http://www.google.com/url?&q=example> Accept-Language: en-US,en

که خط اول این درخواست یا خط شروع درخواست که به کلمه GET شروع شده رو میتونیم به 3 قسمت مجزا تقسیم کنیم :

قسمت اول خود همین کلمه کلیدی GET هستش که اون رو به عنوان HTTP Verb یا HTTP methods میشناسیم ، این کلمه و یسکری دیگه از کلمات کلیدی دیگه مثل POST و PUT و... هدف ما رو از ارتباط سرور مشخص میکنند .GET یعنی گرفتن و در اینجا منظور ما این است که میخواهیم از این URL مد نظر اطلاعات رو بخونیم یا دریافت کنیم.

قسمت دوم در خط اول میشه [<https://www.example.com/description.html>](<https://www.example.com/description.html>) که بهش مسیر درخواست یا Path میگیم .

و در آخر این خط هم ورژن درخواست HTTP مشخص شده که برابر است با HTTP/1.1

بعد از این خط چیز هایی که میبنید به عنوان header درخواست شناخته میشن که شامل زبان درخواست ، نوع درخواست و غیره هستش. هر header می تواند شامل متا دیتا های مختلفی باشد تا سرور بهتر بفهمد چه نوع اطلاعاتی ازش درخواست میشه.

و البته هر درخواست میتواند شامل بخشی به نام body یا بدنه درخواست باشد ( در این مثال بدنه درخواست وجود ندارد ) که شامل اطلاعاتی هستند که میخواهیم آنها را در سرور ذخیره نماییم !

به طور خلاصه هر درخواست HTTP شامل خط شروع (که با فعل های HTTP شروع میشه ) و سپس header و body درخواست میتونه باشه . که اشاره شد با توجه به درخواست میتونه شامل header های متفاوت باشیم و body درخواست هم بسته به هدف ما از ارتباط با سرور میتونه وجود داشته باشه یا نداشته باشه !

خب حالا بریم ببینیم یک پاسخ ساده یا Response از نوع HTTP چجوری هستش :

HTTP/1.1 200 OK Content-Type: text/html; charset=utf-8 Server: Apache/2.4 Date: Sun, 01 Nov 2020 16:38:23 GMT Content-Length: 17151 <html> <head> <title>Page Title Here</title> </head> <body> Content here </body> </html>

بازم مثل قبل در خط اول پاسخ دریافتی از سرور اطلاعات مهمی وجود داره که شامل ورژن HTTP هستش و سپس بعد از اون یک شماره را سرور به سمت کلاینت ارسال کرده که برابر عدد 200 هستش ، این اعداد برگشتی بسیار مهم هستن و هر عدد مفهموم دقیق و خاصی رو داره که به این اعداد HTTP status code یا کد های وضعیت میگیم . سرور با توجه به پاسخی که به ما میده عدد خاصی رو بازگشت میده که کد یا عدد 200 یعنی اینکه عملیات درخواست / پاسخ موفقیت آمیز بوده ، و بعد از این عدد هم کلمه OK هستش که به اون HTTP status reason میگیم که اشاره به همین موضوع موفقیت آمیز بودن عملیات درخواست / پاسخ اشاره میکنه ، و فرمت اون از نوع text هستش .

و بعد از خط اول هدر های پاسخ اومدن که یکسری اطلاعات metadata در مورد پاسخ اسالی ، از جمله اندازه کل body پاسخ به صورت بایت و زمان پاسخ و غیره میشه.

و در نهایت، پاسخ شامل محتویات body هستش که یک صفحه html رو به سمت کلاینت بازگشت داده است.

هدر های HTTP

ده‌ها فیلد هدر وجود دارد که می‌توانند از طریق HTTP ارسال شوند، و هم کلاینت‌ها و هم سرورها می‌توانند هدرهای دیگری را که خودشون تعریف کرده‌اند رو نیز ارسال کنن.

برخی از رایج ترین هدرها عبارتند از:

برای رکوئست ها یا درخواست ها از سمت کلاینت :

1- اطلاعات کابر یا User-Agent: رشته ای که نوع و ورژن کلاینت را توصیف می کند

2- کوکی: قطعه کوچکی از داده که قبلاً توسط سرور برای کمک به ردیابی این کلاینت پیوست شده است

3- ارجاع دهنده یا Referer: آدرس صفحه قبلی که روی لینک آن کلیک شده است

برای پاسخ هایی که از سمت سرور می آید :

1- طول پاسخ یا Content-Length: اندازه پاسخ که بر حسب بایت است.

2- مکان یا Location : تغییر مسیر درخواست به یک URL جدید

3- تنظیم مجدد کوکی Set-Cookie: یک مقدار کوکی جدید را ایجاد می کند

فصل مشترک در سمت کلاینت و سرور :

مقدار Content-Type: نام فرمت مورد استفاده در بدنه درخواست / پاسخ را مشخص میکنیم در این فیلد .

متد های HTTP

پروتکل HTTP چندین متد را در دسترس ما قرار می دهد و هر متد HTTP نوع متفاوتی از هدف درخواست را نشان می دهد :

1- متد GET: کلاینت می خواهد اطلاعات را دریافت کند .

2- متد POST: کلاینت می خواهد داده ها را روی سرور ایجاد یا آپدیت کند ،این متد برای ارسال اطلاعات به سمت سرور استفاده میشه . ارسال اطلاعات یا دیتا ها بوسیله این متد بیشتر برای ایجاد اطلاعات است تا آپدیت اطلاعات . ولی خب با این متد هم قادریم که اطلاعات رو در سرور (دیتابیس ) آپدیت کنیم ! در حالت کلی در ذهن خودتون اینطور به خاط بسپارید که برای ارسال اطلاعات از این متد استفاده میشه !

3- متد PUT: کلاینت می خواهد داده های سرور را آپدیت یا جایگزین کند . از این متد برای آپدیت کردن دیتا استفاده میکنیم .

4- متد DELETE: کلاینت می خواهد برخی از داده های سرور را حذف کند

5- متد PATCH : عملکرد آن شبیه به متد PUT است ولی برای آپدیت جزئی یا آپدیت یک قسمت از دیتا استفاده می شود

6- متد های HEAD و OPTIONS رو هم داریم که نحوه کارکردشون رو به خود شما میسپارم ! :)

هر متد HTTP تغییرات مختلفی در نحوه قالب بندی درخواست را ایجاد میکند ، یعنی اینکه مثلا قالب درخواست GET در بعضی از اطلاعات ارسالی میتونه متفاوت با قالب درخواست POST و غیره باشه ، و بسته به نیاز های کلاینت ایجاد می شود . و نکته مهم این است که علاوه بر این، برخی از انواع درخواست‌ها را می‌توان به‌عنوان «بی‌توان» یا "idempotent” در نظر گرفت (می‌توان چندین بار بدون ایجاد تغییرات اضافی آن درخواست را انجام داد).

خب چون این متد ها بسیار پرکاربرد هستن و درک اونها برای یک دولوپر خیلی ضروریه درادامه اونها رو بیشتر توضیح میدیم :

درخواست GET :

درخواست های GET برای بازیابی و گرفتن اطلاعات از سرور، بر اساس یک URL خاص استفاده می شوند .این درخواست های شامل body یا بدنه درخواست نمی باشند. با این حال کلاینت ها میتوانند داده های اضافی را به عنوان query parameters یا query string به URL اصلی متصل کنند . این کوئری استرینگ ها به عنوان یک اضافه شونده به URL هستند که برای کمک به تعریف محتوا یا اقدامات خاص بر اساس داده های ارسال شده استفاده می شوند.

این کوئری استرینگ ها با علامت سوال ؟ شروع میشوند و فرمت آهنا به صورت key=value است و اگر چندتا از آنها را نیاز باشد که ارسال کنیم آنها را با علامت & یا ampersands از هم دیگر جدا میکنیم.

مانند :

/endpoint?a=1&b=stuff

در کوئری پارامتر ها space ها و کارکترهای خاص در URLها ممکن است نیاز به کد گذاری URL ای داشته باشند.

(منظور انجام عملیات URL-encoded است ) و در جاهایی ممکن است که مقدار اصلی با یک درصد و یک عدد جایگزین شود ، مانند مثل زیر که space با علامت % و عدد 20 جایگزین شده است

?a=Some Value ممکن است تبدیل بشود به مقدار زیر ?a=Some%20Value

از آنجایی که درخواست های GET فقط برای دریافت داده ها استفاده می شود، سرورها نیاز نیست که داده ها را در پاسخ به GET به روز کنند. این بدان معناست که انجام دادن چندین باره درخواست GET بدون ایجاد عوارض جانبی یا ساید افکت ها ( side effect=changing something somewhere ) هستند و از این نظر ایمن هستند .

درخواست های POST :

درخواست های POST برای اینکه به سرور بگوییم اطلاعات ارسالی را ذخیره نماید یا برخی داده ها را به روز کند یا برخی از اطلاعات را پردازش کند استفاده می شود . POST ها معمولاً تمام اطلاعات را در بدنه یا body درخواست قرار می دهند و به ندرت شامل کوئری استرینگ ها می شوند .

بدنه ها یا body درخواست های POST معمولا از چند فرمت رایج زیر استفاده می کنند :

الف : "Form-encoded” : همان ساختار Key / Value به عنوان کوئری استرینگ ها هستش، اما در بدنه یک POST قرار می گیرد .

ب :"Multi-part form data” : یک قالب محدود که بدنه درخواست را به بخش هایی تقسیم می کند .

ج : "JSON” : نمایش رشته ای از ساختارهای داده جاوا اسکریپت مانند اشیا و آرایه ها .

درخواست های PUT :

عملکرد و هدف از درخواست های PUT بسیار شبیه به درخواست های POST است و این درخواست ها شامل ارسال داده به سرور با قصد به روز رسانی است !

تفاوت مورد نظر در این است که یک درخواست PUT برای ایجاد ( create ) یا جایگزینی ( replace) یک مقدار در نظر گرفته شده است، در حالی که یک POST برای ایجاد ( create ) یا به روز رسانی ( update ) یک مقدار در نظر گرفته شده است.

از نظر مفهومی، یک درخواست PUT باید چندین بار پشت سر هم انجام شود، در حالی که یک درخواست POST احتمالاً باعث می شود در هر درخواست اتفاقی جداگانه و متمایزی رخ دهد.

درخواست های PATCH :

درخواست‌های PATCH نیز مشابه درخواست‌های PUT هستند، اما هدف از ارسال آنها فرستادن یک مقدار جزئی از یک آیتم یا دیتا است، در حالی که PUT به معنای ارسال کامل یک آیتم است.

درخواست های DELETE :

درخواست های DELETE برای ارسال درخواست به سرور برای حذف برخی از داده ها استفاده می شود. از نظر مفهومی، ارسال چندین بار درخواست DELETE ایمن است چونکه اگر مقداری قبلاً از بین رفته و پاک شده باشد، سرور باید درخواست مجدد را نادیده بگیرد .

خب برای اینکه خیلی طولانی نشه این قسمت بقیه مطلب در پست بعدی منتشر می کنم .

قسمت دوم

httpserverdnshttp verbسمت کلاینت
یک گیک کامپیوتر و تکنولوژی
شاید از این پست‌ها خوشتان بیاید