این پست پاسخ به سوالی است که در یکی از مقالات من پرسیده شده است.
در این مقاله می خواهم به شما بگویم که روش های HTTP GET / POST / PUT / DELETE و سایر روش های HTTP چیست، برای چه چیزی اختراع شده اند و چگونه از آنها مطابق با REST استفاده کنید.
HTTP
پس دقیقاً یکی از پروتکل های اصلی اینترنت چیست؟ پدانت ها رو به RFC2616 میفرستم و بقیه رو مثل آدم میگم :)این پروتکل ارتباط بین دو کامپیوتر (کارفرما و سرور) را بر اساس پیام هایی به نام Request و Response توصیف می کند. هر پیام از سه بخش تشکیل شده است: خط شروع، سرصفحه ها و بدنه. در این مورد، فقط خط شروع مورد نیاز است.
خطوط شروع درخواست و پاسخ فرمت متفاوتی دارند - ما فقط به خط شروع درخواست علاقه مند هستیم که به نظر می رسد:
روش URI HTTP / VERSION ,
در جایی که METHOD فقط روش درخواست HTTP است، URI شناسه منبع است، VERSION نسخه پروتکل است (نسخه 1.1 در حال حاضر مرتبط است).
سرصفحه ها مجموعه ای از جفت نام-مقدار هستند که با دو نقطه از هم جدا شده اند. اطلاعات خدمات مختلفی در سربرگ ها منتقل می شود: رمزگذاری پیام، نام و نسخه مرورگر، آدرسی که مشتری از آن آمده است (ارجاع کننده) و غیره.
بدنه پیام در واقع داده های ارسال شده است. در پاسخ، داده های ارسال شده، قاعدتاً صفحه html است که مرورگر درخواست کرده است و در درخواست، به عنوان مثال، در متن پیام، محتوای فایل های آپلود شده به سرور منتقل می شود. اما به عنوان یک قاعده، بدنه پیام به هیچ وجه شامل درخواست نمی شود.
مثال ارتباط HTTP
بیایید به یک مثال نگاه کنیم.استعلام:
دریافت /index.php HTTP / میزبان 1.1: example.com عامل کاربر: Mozilla / 5.0 (X11; U; Linux i686; ru; rv: 1.9b5) Gecko / 2008050509 Firefox / 3.0b5 پذیرش: متن / html اتصال: بستن
خط اول خط درخواست است، بقیه هدرها هستند. متن پیام گم شده است
پاسخ:
HTTP / 1.0 200 OK سرور: nginx / 0.6.31 Content-Language: ru Content-نوع: text / html; charset = utf-8 Content-Length: 1234 اتصال: بستن ... صفحه HTML خود ...
منابع و روش ها
بیایید به رشته جستجوی شروع بازگردیم و به یاد داشته باشیم که شامل پارامتری مانند URI است. این مخفف Uniform Resource Identifier - یک شناسه منبع یکنواخت است. یک منبع، به طور معمول، یک فایل روی سرور است (یک مثال URI در این مورد "/styles.css" است)، اما به طور کلی، یک منبع می تواند یک شی انتزاعی باشد ("/ blogs / webdev /" - نشان می دهد. بلوک "توسعه وب"، و نه برای یک فایل خاص).نوع درخواست HTTP (که روش HTTP نیز نامیده می شود) به سرور می گوید که ما می خواهیم چه اقدامی با منبع انجام دهیم. در ابتدا (در اوایل دهه 90) فرض بر این بود که مشتری فقط می تواند یک چیز از منبع بخواهد - دریافت آن ، اما اکنون با استفاده از پروتکل HTTP می توانید پست ایجاد کنید ، نمایه را ویرایش کنید ، پیام ها را حذف کنید و موارد دیگر. و ترکیب این اقدامات با اصطلاح "دریافت" دشوار است.
برای تمایز اقدامات با منابع در سطح روش های HTTP، گزینه های زیر اختراع شد:
- GET - گرفتن منبع
- POST - ایجاد یک منبع
- PUT - به روز رسانی منابع
- DELETE - حذف یک منبع
REST وارد بازی می شود
REST (انتقال دولتی نمایندگی) - این اصطلاح در سال 2000 توسط روی فیلدینگ - یکی از توسعه دهندگان پروتکل HTTP - به عنوان نامی برای گروهی از اصول برای ساخت برنامه های کاربردی وب ابداع شد. به طور کلی، REST منطقه وسیع تری را نسبت به HTTP پوشش می دهد - می توان از آن در شبکه های دیگر با پروتکل های دیگر استفاده کرد. REST اصول تعامل مشتری و سرور را بر اساس مفاهیم "منبع" و "فعل" توصیف می کند (شما می توانید آنها را به عنوان موضوع و محمول درک کنید). در مورد HTTP، منبع با URI آن تعریف می شود و فعل روش HTTP است.REST پیشنهاد می کند استفاده از یک URI برای منابع مختلف (یعنی آدرس دو مقاله مختلف مانند /index.php?article_id=10 و /index.php?article_id=20 یک راه REST نیستند) کنار گذاشته شود و استفاده شود. روش های مختلف HTTP برای اقدامات مختلف یعنی یک برنامه وب که با رویکرد REST نوشته شده است، هنگام دسترسی به آن منبع با روش HTTP DELETE آن را حذف می کند (البته این بدان معنا نیست که شما باید بتوانید همه چیز و همه چیز را حذف کنید، اما هردرخواست حذف برنامه باید از روش HTTP DELETE استفاده کند).
REST به برنامه نویسان توانایی نوشتن برنامه های وب استاندارد و کمی زیباتر از همیشه را می دهد. با استفاده از REST، URI برای افزودن کاربر جدید /user.php?action=create (روش GET / POST) نیست، بلکه به سادگی /user.php (روش دقیق POST) خواهد بود.
در نتیجه، با ترکیب مشخصات HTTP موجود و رویکرد REST، روشهای مختلف HTTP در نهایت معنا پیدا میکنند. GET - یک منبع را برمی گرداند، POST - یک منبع جدید ایجاد می کند، PUT - یک موجود را به روز می کند، DELETE - حذف می کند.
چالش ها و مسائل؟
بله، یک مشکل کوچک برای اعمال REST در عمل وجود دارد. این مشکل HTML نام دارد.درخواستهای PUT/DELETE را میتوان از طریق XMLHttpRequest، با تماس با سرور "به صورت دستی" (مثلاً از طریق curl یا حتی از طریق telnet) ارسال کرد، اما نمیتوانید یک فرم HTML برای ارسال یک درخواست کامل PUT / DELETE ایجاد کنید.
نکته این است که مشخصات HTML به شما اجازه ایجاد فرم هایی را نمی دهد که داده ها را به جز از طریق GET یا POST ارسال کنند. بنابراین، برای عملکرد عادی با روش های دیگر، باید آنها را به طور مصنوعی تقلید کنید. به عنوان مثال، در Rack (مکانیسمی که توسط آن Ruby با وب سرور تعامل می کند؛ Rails، Merb و سایر چارچوب های Ruby با استفاده از Rack ساخته می شوند)، می توانید یک فیلد مخفی به نام "_method" را به فرم اضافه کنید و نام آن را مشخص کنید. روش به عنوان مقدار (به عنوان مثال، "PUT") - در این مورد، یک درخواست POST ارسال می شود، اما Rack می تواند وانمود کند که یک PUT دریافت کرده است، نه یک POST.
در حال حاضر، تنها دو روش HTTP بیشتر مورد استفاده قرار می گیرد: GET و POST. اما معلوم شد که حتی در میان این دو "کاج" توسعه دهندگان وب موفق به گم شدن می شوند. توضیحی برای این وجود دارد: از هر دو روش می توان برای به دست آوردن یک نتیجه استفاده کرد. اما باید به خاطر داشت که استفاده نادرست از هر یک از روشها میتواند منجر به عواقب فاجعهباری از جمله بارهای زیاد روی کانال و حفرههای امنیتی شود.
برای جلوگیری از این امر کافی است که هدف و تفاوت های این روش ها را با جزئیات بیشتر درک کنید.
اگر در معنای نام روش ها عمیق شوید، خیلی چیزها روشن می شود. GET (از انگلیسی به دریافت)، یعنی. باید برای پرس و جو از داده ها استفاده شود. POST (از انگلیسی ارسال با پست) - ما از آن برای ارسال داده ها به سرور استفاده می کنیم. به نظر می رسد همه چیز بسیار ساده و قابل درک است. اما کسانی که می خواهند سایت هایی کمی پیچیده تر از سایت کارت ویزیت با یک فرم بازخورد توسعه دهند، بهتر است با این موضوع بیشتر آشنا شوند.
درخواست های HTTP ایمن و ناامن
مشخصات HTTP 1.1 دو مفهوم را معرفی می کند: یک درخواست امن و یک درخواست ناامن، یا به طور دقیق تر، یک روش.
روش های ایمن روش هایی هستند که فقط می توانند اطلاعات را درخواست کنند. آنها نمی توانند منبع درخواستی را تغییر دهند، نمی توانند منجر به نتایج نامطلوب برای کاربر، سایر افراد یا سرور شوند. نمونه هایی از ایمن ها درخواست کد HTML یک صفحه وب یا تصویر هستند. روش های ایمن HEAD و GET هستند.
یادداشت
در واقعیت، صنعتگران البته می توانند با درخواست های GET آسیب وارد کنند. به عنوان مثال، حلقه های پرس و جو.
پرس و جوهای ناامن، همانطور که همه قبلاً حدس زده اند، در صورت استفاده مجدد می توانند به عواقب بدی منجر شوند. چنین درخواست هایی می توانند محتوای منبع مورد دسترسی را تغییر دهند. نمونه هایی از این درخواست ها: ارسال پیام، ثبت نام، پرداخت آنلاین. روش های ناامن عبارتند از POST، PUT، DELETE.
روش های بی توان
Idempotency یکی از ویژگیهای روشهایی است که با تماسهای مکرر متعدد، نتیجه یکسانی را نشان میدهد، مگر اینکه اطلاعات قدیمی باشد. این بدان معنی است که هنگام دسترسی به یک URL، همه کاربران صفحه وب، تصویر، ویدیو و غیره مشابهی را مشاهده خواهند کرد. متدهای GET, PUT, DELETE این ویژگی را دارند.
حال بیایید نگاهی دقیقتر به خود متدهای GET و POST بیندازیم: بیایید یک «خلاصه» کوتاه برای هر کدام بنویسیم.
گرفتن
- طراحی شده برای دریافت داده ها از سرور؛
- بدنه درخواست خالی است.
- به دلیل خالی بودن بدنه درخواست، در سمت سرور سریعتر و با مصرف کمتر منابع سرور پردازش می شوند.
- انتقال متغیرها در نوار آدرس اتفاق می افتد (کاربر آن را اینگونه می بیند، از نظر فنی داده ها در خط پرس و جو منتقل می شوند) و بنابراین اطلاعات مربوط به متغیرها و مقادیر آنها قابل مشاهده است (داده ها محافظت نمی شوند).
- قادر به انتقال مقدار کمی داده به سرور: محدودیت هایی در طول URL وجود دارد که بستگی به مرورگر دارد، به عنوان مثال IE6 = 2Kb. این عددی است که توسعه دهندگان یاهو هدف قرار دادن آن را توصیه می کنند.
- فقط می تواند کاراکترهای ASCII را منتقل کند.
- چنین درخواستی را می توان کپی، ذخیره کرد (به عنوان مثال، در نشانک ها)؛
- درخواست را می توان کش کرد (این را می توان کنترل کرد).
- درخواست های مشروط و جزئی برای کاهش بیشتر بار روی کانال و سرور موجود است.
- اتصال HTTP را قطع نمی کند (زمانی که حالت keepAlive در سرور فعال است).
پست
- طراحی شده برای ارسال داده ها به سرور؛
- انتقال داده در بدنه درخواست اتفاق می افتد.
- پردازش سمت سرور کندتر و "سنگین تر" از GET است، زیرا علاوه بر هدرها، باید بدنه درخواست را نیز تجزیه کنید.
- قادر به انتقال حجم زیادی از داده ها؛
- قابلیت انتقال فایل ها
- صفحه ایجاد شده با روش POST قابل نشانک گذاری نیست.
- اتصال HTTP را قطع می کند.
- برای انتقال حتی مقدار بسیار کمی از اطلاعات، اکثر مرورگرها حداقل دو بسته TCP ارسال می کنند: هدر و سپس بدنه درخواست.
معلوم می شود که این دو روش چندان شبیه هم نیستند. استفاده از این یا آن باید بر اساس وظیفه در دست تعیین شود، نه با این واقعیت که GET به طور پیش فرض استفاده می شود یا کار با آن آسان تر است. GET مطمئناً در بیشتر موارد گزینه بهتری است، به خصوص هنگام ساخت AJAX های سریع، اما معایب آن را فراموش نکنید. برای خودم، یک الگوریتم ساده در مورد انتخاب روش ایجاد کردم.
1. پروتکل HTTP. معرفی
فقط می خواهم یک چیز کوچک را روشن کنم. کلمه وحشتناک پروتکل چیزی نیست جز توافق بسیاری از مردم، فقط در یک لحظه خوب مردم تصمیم گرفتند: "بیایید این کار را انجام دهیم، و سپس همه چیز درست می شود." چیزی برای ترس وجود ندارد، همه چیز فقط ظالمانه است و ما اکنون این خشم را باز خواهیم کرد. پس این پروتکل HTTP چیست و با چه چیزی خورده می شود؟
1.1 مشتری و سرور
هیچ معجزه ای در دنیا وجود ندارد و حتی بیشتر از آن در دنیای برنامه نویسی و اینترنت! این را به عنوان یک حقیقت تزلزل ناپذیر درک کنید. و اگر برنامه کار نمی کند یا آنطور که می خواهید کار نمی کند، به احتمال زیاد، یا اشتباه نوشته شده است یا حاوی خطاهایی است. بنابراین چگونه مرورگر از سرور درخواست می کند که چیزی برای آن ارسال کند؟ خیلی ساده است! شما فقط باید کمی استراحت کنید و از این روند لذت ببرید :-)
1.2. نوشتن اولین درخواست HTTP ما
اگر فکر می کنید همه چیز خیلی پیچیده است، در اشتباهید. یک شخص آنقدر ساخته شده است که به سادگی قادر به ایجاد چیزی پیچیده نیست، در غیر این صورت خودش در این مورد گیج می شود :-) بنابراین، یک مرورگر وجود دارد و یک وب سرور وجود دارد. مرورگر همیشه آغازگر تبادل اطلاعات است. یک وب سرور هرگز فقط چیزی را برای کسی ارسال نمی کند، به طوری که چیزی را به مرورگر می فرستد - به مرورگر نیاز دارد که آن را بخواهد. ساده ترین درخواست HTTP ممکن است به شکل زیر باشد:
دریافت http: //www.php.net/ HTTP / 1.0rnrn
* GET (ترجمه شده از انگلیسی به معنای "دریافت") - نوع درخواست، نوع درخواست می تواند متفاوت باشد، به عنوان مثال POST، HEAD، PUT، DELETE (در زیر برخی از آنها را در نظر خواهیم گرفت).
* http://www.php.net/ - URI (آدرس) که می خواهیم حداقل اطلاعاتی را از آن به دست آوریم (البته امیدواریم صفحه HTML را دریافت کنیم).
* HTTP / 1.0 - نوع و نسخه پروتکلی که در فرآیند ارتباط با سرور استفاده خواهیم کرد.
* rn - انتهای خط، که باید دو بار تکرار شود، چرا، کمی بعد مشخص می شود.
شما می توانید این درخواست را به راحتی انجام دهید. برنامه telnet.exe را اجرا کنید، www.php.net را به عنوان میزبان وارد کنید، پورت 80 را مشخص کنید و به سادگی با فشار دادن اینتر با دوبار rnrn این کوئری را تایپ کنید. در پاسخ کد HTML صفحه اصلی وب سایت www.php.net را دریافت خواهید کرد.
1.3 ساختار پرس و جو
بیایید نگاهی بیندازیم که درخواست HTTP از چه چیزی تشکیل شده است. همه چیز به اندازه کافی ساده است. برای شروع، درخواست HTTP یک متن معنادار است. در حالت کلی شامل چه مواردی می شود؟ بیایید پروتکل HTTP 1.0 را در نظر بگیریم. بنابراین :
درخواست - خط [عمومی - سربرگ | درخواست - سربرگ | Entity - Header] rn [Entity - Body]
* خط درخواست - خط درخواست
*
فرمت : "درخواست روش-URI HTTP-Versionrn"
* روش -روشی که منبع Request-URI را مدیریت می کند می تواند GET، POST، PUT، DELETE یا HEAD باشد.
* Request-URI یک پیوند نسبی یا مطلق به یک صفحه با مجموعه ای از پارامترها است، برای مثال /index.html یا http://www.myhost.ru/index.html یا /index.html?a=1&b= qq در مورد دوم، یک درخواست با مجموعه ای از متغیرهای a و b با مقادیر مربوطه به سرور ارسال می شود و نماد علامت "&" به عنوان جداکننده بین پارامترها عمل می کند.
* نسخه HTTP - نسخه پروتکل HTTP، در مورد ما "HTTP / 1.0".
ما بسیار علاقه مند به روش های پردازش GET و POST هستیم. با متد GET می توانید به سادگی پارامترها را به اسکریپت منتقل کنید و با متد POST می توانید فرم ارسالی را شبیه سازی کنید.
برای متد GET، Request-URI ممکن است به این صورت باشد: "/index.html?param1=1¶m2=2".
* General-Header - قسمت اصلی هدر.
قالب:
فقط می تواند دو پارامتر داشته باشد: تاریخ یا پراگما. تاریخ - زمان گرینویچ در قالب "روز هفته، روز ماه سال HH: MM: SS GMT"، به عنوان مثال، "سه شنبه، 15 نوامبر 1994 08:12:31 GMT" - تاریخ درخواست. Pragma می تواند یک مقدار داشته باشد، بدون کش، که کش کردن صفحه را غیرفعال می کند.
* Request-Header - بخشی از هدر که درخواست را توصیف می کند.
Request-Header می تواند پارامترهای زیر را داشته باشد : Allow, Authorization, From, If-Modified-Since, Referer, User-Agent.
ما پارامتر Autorization را در این فصل پوشش نمی دهیم، زیرا برای دسترسی به منابع خصوصی استفاده می شود، که اغلب مورد نیاز نیست. می توانید به طور مستقل شکل گیری هدر را برای دسترسی مجاز در سایت www.w3c.org مطالعه کنید.
* Allow - روش های پردازش قابل قبول را تنظیم می کند.
قالب: "مجاز: GET | HEADn".
هنگام تعیین روش پردازش POST در Request-Line، این پارامتر نادیده گرفته می شود. روش های قابل قبول برای پردازش درخواست را مشخص می کند. پروکسی های سرور پارامتر Allow را تغییر نمی دهند و بدون تغییر به سرور می رسد.
* از - آدرس ایمیلی که درخواست را ارسال کرده است.
قالب: "از: adderssrn".
به عنوان مثال، "از: [ایمیل محافظت شده]".
* If-Modified-Since - نشان می دهد که درخواست از زمان فلان زمان تغییر نکرده است.
قالب: "If-Modified-Since: Datern"
فقط برای روش پردازش GET استفاده می شود. تاریخ در زمان گرینویچ با همان فرمت پارامتر Date در General-Header است.
* ارجاع دهنده - یک پیوند مطلق به صفحه ای که درخواست از آن آغاز شده است، یعنی پیوندی به صفحه ای که کاربر از آن به صفحه ما رفته است.
قالب: "ارجاع دهنده: urln".
مثال: "ارجاع دهنده: www.host.ru/index.htmln".
* User-Agent - نوع مرورگر.
به عنوان مثال: "User-Agent: Mozilla / 4.0n"
* Entity-Header - بخشی از هدر که داده های Entity-Body را توصیف می کند.
در این قسمت از درخواست، پارامترهایی تنظیم می شوند که بدنه صفحه را توصیف می کنند. Entity-Header می تواند شامل پارامترهای زیر باشد: Allow، Content-Encoding، Content-Length، Content-Type، Expires، Last-Modified، extension-header.
* Allow - پارامتری شبیه به Allow از General-Header.
* Content-Encoding - نوع رمزگذاری داده های Entity-Body.
قالب: "کدگذاری محتوا: x-gzip | x-compress | نوع دیگر".
مثال: "Content-Encoding: x-gzipn". علامت "|" یعنی کلمه «یا» یعنی این یا آن یا آن و غیره.
نوع دیگری ممکن است راهی را برای رمزگذاری داده ها نشان دهد، به عنوان مثال، برای روش POST: "Content-Encoding: application / x-www-form-urlencodedn".
* Content-Length - تعداد بایت های ارسال شده به Entity-Body. مقدار Content-Length معنای کاملاً متفاوتی برای داده های ارسال شده در قالب MIME دارد، جایی که به عنوان پارامتری برای توصیف یک قطعه داده عمل می کند - "external / entity-body". اعداد صحیح از صفر یا بیشتر معتبر هستند.
مثال: "Content-Length: 26457n".
* نوع محتوا - نوع داده های ارسال شده.
به عنوان مثال: "Content-Type: text / htmln".
* منقضی می شود - زمانی که صفحه باید از کش مرورگر حذف شود.
قالب: "انقضا: تاریخ". فرمت تاریخ مشابه فرمت تاریخ برای پارامتر Date از General-Header است.
* Last-Modified - زمان آخرین اصلاح داده های ارسال شده.
قالب: "آخرین تغییر: تاریخ". فرمت تاریخ مشابه فرمت تاریخ برای پارامتر Date از General-Header است.
* Extention-header - بخشی از هدر که می تواند برای پردازش توسط مرورگر یا برنامه دیگری که سند را می پذیرد در نظر گرفته شود. در این قسمت می توانید پارامترهای خود را با فرمت "ParameterName: parametervaluen" توضیح دهید. اگر برنامه کلاینت نداند چگونه آنها را مدیریت کند، این پارامترها نادیده گرفته می شوند.
به عنوان مثال: "کوکی: r = 1rn" - کوکی های شناخته شده را برای صفحه تنظیم می کند.
و اکنون، پس از چنین کلمات وحشتناک، بیایید سعی کنیم کمی آرام شویم و بفهمیم که به چه چیزی نیاز داریم؟ ما به طور طبیعی با مثال ها متوجه خواهیم شد.
بیایید تصور کنیم که باید با انتقال کوکی ها صفحه ای از سایت دریافت کنیم، در غیر این صورت به سادگی به عنوان مهمان ناخوانده فرستاده می شویم و علاوه بر این، مشخص است که این صفحه تنها پس از بازدید از صفحه اصلی سایت مجاز به ورود است. .
2 روش GET
بیایید درخواست خود را بنویسیم.
دریافت http:
میزبان: www. سایت. فرار کن
کوکی: درآمد = 1rn
rn
این درخواست به ما می گوید که می خواهیم محتوای صفحه را در http://www.site.ru/news.html با استفاده از روش GET دریافت کنیم. قسمت Host نشان می دهد که این صفحه در سرور www.site.ru قرار دارد، قسمت Referer نشان می دهد که ما برای اخبار از صفحه اصلی سایت آمده ایم و قسمت Cookie نشان می دهد که فلان کوکی به آن اختصاص داده شده است. ما چرا میزبان، مرجع و کوکی اینقدر مهم هستند؟ زیرا برنامه نویسان عادی هنگام ایجاد سایت های پویا، این فیلدهایی را که در اسکریپت ها (از جمله PHP) به صورت متغیر ظاهر می شوند، بررسی می کنند. این برای چیست؟ به عنوان مثال، برای جلوگیری از سرقت سایت، یعنی. برنامه ای برای دانلود خودکار روی آن قرار نداده است یا اینکه شخصی که وارد سایت می شود همیشه فقط از صفحه اصلی و غیره به آن دسترسی داشته باشد.
حال تصور کنید که باید فیلدهای فرم را در صفحه پر کنیم و درخواستی از فرم ارسال کنیم، اجازه دهید این فرم دارای دو فیلد باشد: ورود و رمز عبور (ورود و رمز عبور) - و البته ما ورود و رمز عبور را می دانیم. .
دریافت http: //www.site.ru/news.html?login=Petya%20Vasechkin&password=qq HTTP / 1.0rn
میزبان: www. سایت. فرار کن
مرجع: http://www.site.ru/index.htmlrn
کوکی: درآمد = 1rn
rn
با ما وارد شوید "Petya Vasechkin" چرا باید Petya% 20Vasechkin را بنویسیم؟ این به این دلیل است که کاراکترهای خاص می توانند توسط سرور به عنوان نشانه های یک پارامتر جدید یا پایان یک درخواست و غیره شناسایی شوند. بنابراین، الگوریتمی برای رمزگذاری نام پارامترها و مقادیر آنها وجود دارد تا از موقعیت های غیر منتظره در درخواست جلوگیری شود. شرح کامل این الگوریتم را می توانید در اینجا بیابید و PHP دارای توابع rawurlencode و rawurldcode به ترتیب برای رمزگذاری و رمزگشایی است. می خواهم توجه داشته باشم که اگر پارامترهای کدگذاری شده در درخواست ارسال شوند، PHP خودش رمزگشایی می کند. این جایی است که من اولین فصل از معرفی خود را با پروتکل HTTP آغاز می کنم. در فصل بعدی، ما به ساخت درخواست های POST (در ترجمه از انگلیسی - "ارسال") نگاه خواهیم کرد که بسیار جالب تر خواهد بود، زیرا این نوع درخواست هنگام ارسال داده ها از فرم های HTML استفاده می شود.
3. روش POST.
در مورد درخواست HTTP POST، دو گزینه برای انتقال فیلدها از فرمهای HTML وجود دارد، یعنی استفاده از الگوریتمهای برنامه / x-www-form-urlencoded و multipart/form-data. تفاوت بین این الگوریتم ها بسیار قابل توجه است. واقعیت این است که اولین نوع الگوریتم مدت ها پیش ایجاد شد، زمانی که زبان HTML هنوز امکان انتقال فایل ها از طریق فرم های HTML را فراهم نمی کرد. پس بیایید با مثال نگاهی به این الگوریتم ها بیندازیم.
3.1 نوع محتوا: برنامه کاربردی / x-www-form-urlencoded.
ما درخواستی مشابه درخواست GET خود برای انتقال لاگین و رمز عبور می نویسیم که در فصل قبل مورد بحث قرار گرفت:
ارسال http: //www.site.ru/news.html HTTP / 1.0rn
میزبان: www. سایت. فرار کن
مرجع: http://www.site.ru/index.htmlrn
کوکی: درآمد = 1rn
محتوا - نوع: برنامه کاربردی / x - www - فرم - urlencodedrn
محتوا - طول: 35rn
rn
در اینجا نمونه ای از استفاده از فیلدهای هدر Content-Type و Content-Length را مشاهده می کنیم. Content-Length می گوید که ناحیه داده چند بایت را اشغال می کند که توسط خط دیگری rn از هدر جدا می شود. اما پارامترهایی که قبلاً در Request-URI برای درخواست GET قرار داده شده بودند اکنون در Entity-Body هستند. مشاهده می شود که به همین صورت شکل گرفته اند، فقط باید آنها را بعد از عنوان بنویسید. من می خواهم به یک نکته مهم دیگر توجه کنم، هیچ چیز مانع از قرار دادن پارامترها با نام های مختلف در Request-URI به طور همزمان با مجموعه پارامترها در Entity-Body نمی شود، به عنوان مثال:
ارسال http: //www.site.ru/news.html?type=user HTTP / 1.0rn
.....
rn
ورود = Petya% 20Vasechkin و رمز عبور = qq
3.2 نوع محتوا: چند بخشی / فرم-داده
به محض اینکه دنیای اینترنت متوجه شد که ارسال فایل ها از طریق فرم ها نیز خوب است، کنسرسیوم W3C نهایی کردن فرمت درخواست POST را آغاز کرد. در آن زمان، فرمت MIME (افزونه های ایمیل چند منظوره اینترنتی) قبلاً به طور گسترده استفاده می شد، بنابراین، برای اینکه چرخ را دوباره اختراع نکنیم، تصمیم گرفتیم از بخشی از این قالب پیام برای ایجاد درخواست های POST در پروتکل HTTP استفاده کنیم.
تفاوت های اصلی بین این فرمت و نوع برنامه / x-www-form-urlencoded چیست؟
تفاوت اصلی این است که Entity-Body اکنون می تواند به بخش هایی تقسیم شود که با مرزها از هم جدا می شوند. جالبترین چیز این است که هر بخش میتواند عنوان خاص خود را برای توصیف دادههایی که در آن ذخیره میشود، داشته باشد. در یک درخواست، می توانید داده ها را از انواع مختلف انتقال دهید (همانطور که در نامه ایمیل، می توانید فایل ها را همراه با متن انتقال دهید).
پس بیایید شروع کنیم. دوباره همان مثال را در مورد انتقال لاگین و رمز عبور در نظر بگیرید، اما اکنون با فرمت جدید.
ارسال http: //www.site.ru/news.html HTTP / 1.0rn
میزبان: www. سایت. فرار کن
مرجع: http://www.site.ru/index.htmlrn
کوکی: درآمد = 1rn
محتوا - طول: 209rn
rn
- 1BEF0A57BE110FD467Arn
Content - Disposition: form - data; name = "ورود" rn
rn
پتیا واسچکینرن
- 1BEF0A57BE110FD467Arn
Content - Disposition: form - data; name = "رمز عبور" rn
rn
qqrn
- 1BEF0A57BE110FD467A - rn
حالا بیایید بفهمیم چه چیزی نوشته شده است. :-) من عمداً برخی از کاراکترهای rn را به صورت پررنگ مشخص کرده ام تا با داده ها ادغام نشوند. با نگاه دقیق، می توانید فیلد مرزی را بعد از Content-Type ببینید. این فیلد جداکننده بخش - مرز را تنظیم می کند. رشته ای متشکل از حروف و اعداد لاتین، و همچنین تعدادی کاراکتر دیگر (متاسفانه، به یاد ندارم کدام یک) می تواند به عنوان حاشیه استفاده شود. در بدنه درخواست یک "-" به ابتدای حاشیه اضافه می شود و درخواست با یک حاشیه پایان می یابد که کاراکترهای "-" نیز به انتهای آن اضافه می شوند. در درخواست ما دو بخش وجود دارد، اولی فیلد ورود را توضیح می دهد و دومی قسمت رمز عبور را توضیح می دهد. Content-Disposition (نوع داده در بخش) می گوید که این داده از فرم خواهد بود و نام فیلد در قسمت نام تنظیم می شود. اینجا جایی است که هدر بخش به پایان می رسد و سپس ناحیه داده بخش دنبال می شود که مقدار فیلد در آن قرار می گیرد (نیازی به رمزگذاری مقدار نیست!).
میخواهم توجه شما را به این نکته جلب کنم که نیازی به استفاده از Content-Length در سرفصلهای بخش ندارید، اما در هدر درخواست لازم است و مقدار آن به اندازه کل Entity-Body بعد از rn دوم Content است. -طول: 209rn. آن ها Entity-Body با یک فید خط اضافی (که در بخش ها نیز قابل مشاهده است) از عنوان جدا می شود.
حالا بیایید یک درخواست برای انتقال فایل بنویسیم.
ارسال http: //www.site.ru/postnews.html HTTP / 1.0rn
میزبان: www. سایت. فرار کن
مرجع: http://www.site.ru/news.htmlrn
کوکی: درآمد = 1rn
محتوا - نوع: چند قسمتی / فرم - داده. مرز = 1BEF0A57BE110FD467Arn
محتوا - طول: 491 rn
rn
- 1BEF0A57BE110FD467Arn
Content - Disposition: form - data; name = "news_header" rn
rn
نمونه اخبار
- 1BEF0A57BE110FD467Arn
Content - Disposition: form - data; name = "news_file"; نام فایل = "news.txt" rn
محتوا - نوع: برنامه / octet - streamrn
محتوا - انتقال - رمزگذاری: binaryrn
rn
و این هم خبر,
که در فایل اخبار نهفته است... txtrn
- 1BEF0A57BE110FD467A - rn
در این مثال، بخش اول عنوان خبر را فوروارد می کند و بخش دوم فایل news.txt را فوروارد می کند. فرد توجه فیلدهای نام فایل و نوع محتوا را در بخش دوم می بیند. فیلد نام فایل نام فایل آپلود شده و Content-Type نوع فایل است. برنامه / جریان هشتگانه نشان می دهد که این یک جریان داده استاندارد است و Content-Transfer-Encoding: باینری نشان می دهد که این داده باینری است و به هیچ وجه کدگذاری نشده است.
یک نکته بسیار مهم اکثر اسکریپت های CGI توسط افراد باهوش نوشته می شوند، بنابراین آنها دوست دارند نوع فایل ورودی را که در Content-Type است بررسی کنند. برای چی؟ اغلب، آپلود فایل ها در سایت ها برای دریافت تصاویر از یک بازدیدکننده استفاده می شود. بنابراین، خود مرورگر سعی می کند تعیین کند که بازدیدکننده چه نوع فایلی را می خواهد ارسال کند و Content-Type مربوطه را در درخواست درج می کند. اسکریپت پس از دریافت آن را بررسی می کند و مثلاً اگر gif یا jpeg نباشد، این فایل را نادیده می گیرد. بنابراین، هنگام تشکیل یک درخواست به صورت "دستی"، از مقدار Content-Type مراقبت کنید تا به فرمت فایل در حال انتقال نزدیکتر باشد.
تصویر / گیف برای گیف
تصویر / jpeg برای jpeg
تصویر / png برای png
تصویر / tiff برای tiff (که به ندرت استفاده می شود، فرمت بسیار بزرگی است)
در مثال ما درخواستی شکل می گیرد که در آن یک فایل متنی منتقل می شود. به همین ترتیب درخواست انتقال یک فایل باینری تشکیل می شود.
4. پس نوشته.
من فکر می کنم که ارزش ندارد در مورد انتقال درخواست ها به سرور با جزئیات صحبت کنیم. این موضوع صرفاً مربوط به فناوری PHP است :-). کافی است بخش مربوط به عملکردهای کار با سوکت ها یا عملکردهای ماژول CURL در اسناد رسمی PHP را با دقت بخوانید.
با توجه به موارد فوق، امیدوارم اکنون مشخص شده باشد که چرا این سوال: "چگونه می توانم با استفاده از تابع هدر یک درخواست POST تشکیل دهم؟" - بی معنی است تابع هدر (رشته) یک ورودی را فقط به هدر درخواست اضافه می کند، نه به بدنه درخواست.
بازگشت |