نحوه راه اندازی گوشی های هوشمند و رایانه های شخصی پرتال اطلاعاتی
  • خانه
  • اخبار
  • دریافت یا ارسال: کدام را انتخاب کنیم؟ با استفاده از روش های GET و POST.

دریافت یا ارسال: کدام را انتخاب کنیم؟ با استفاده از روش های GET و POST.

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

در این مقاله می خواهم به شما بگویم که روش های 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 - حذف یک منبع
به این واقعیت توجه کنید که مشخصات HTTP سرور را ملزم به درک همه روش ها نمی کند (که در واقع بسیار بیشتر از 4 روش وجود دارد) - فقط GET مورد نیاز است و همچنین به سرور نمی گوید که هنگام دریافت چه کاری باید انجام دهد. درخواست با یک روش خاص این بدان معنی است که سرور به درخواست DELETE /index.php HTTP / 1.1 پاسخ می دهد موظف نیستصفحه index.php را در سرور حذف کنید، درست مانند درخواست GET /index.php HTTP / 1.1 موظف نیستصفحه index.php را به شما برگرداند، می تواند آن را مانند حذف کند :)

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 تشکیل دهم؟" - بی معنی است تابع هدر (رشته) یک ورودی را فقط به هدر درخواست اضافه می کند، نه به بدنه درخواست.

بازگشت

بله، بله، همه یک بار چیزی یاد گرفتند. تنها چیزی که افراد را در این زمینه متمایز می کند این است که آموزش برای کسی آسان است، در حالی که دیگران ماه ها نمی توانند اصل موضوع را دریابند. امروز در مورد درخواست های POST و GET در HTML \ PHP صحبت خواهیم کرد.

خود درخواست‌های POST و GET (از این پس به عنوان درخواست‌های ساده نامیده می‌شوند) مدت‌هاست که در تمام منابع اینترنتی ریشه دارند. اگر ناگهان روزی جایگزینی برای این فناوری ها وجود داشته باشد، احتمالاً به این زودی نخواهد بود و احتمالاً لازم نیست. زیرا درخواست های ما وظیفه تبادل داده بین صفحات اینترنتی را به طور کامل انجام می دهد.

بیایید ابتدا یک درخواست GET را بررسی کنیم. بیایید یک فایل index.php با کد html استاندارد ایجاد کنیم و همچنین یک فرم روی آن قرار دهیم، اجازه دهید فرم سفارش محصول باشد.

در اینجا به برچسب توجه می کنیم فرم... دو پارامتر دارد عملو روش... اولی مسئول آدرس صفحه‌ای است که داده‌های خود را به آن منتقل می‌کنیم، دومی مسئول روشی است که این داده‌ها توسط آن منتقل می‌شوند. در داخل این تگ مجموعه داده های ما که می خواهیم انتقال دهیم توضیح داده شده است. نام ها به داده ها (پارامتر نام). ورودی نوع نیز مورد نیاز است ارسال، که دکمه ای است که برای ارسال داده کلیک می شود.

بیایید فایل خود را ذخیره کرده و در یک مرورگر باز کنیم.
مسیر صفحه ما در مرورگر "... / index.php" است. در خود صفحه شاهد دو فیلد ورودی و یک دکمه هستیم. بیایید چیزی به فیلدهای خود اضافه کنیم و روی دکمه "سفارش" کلیک کنیم. صفحه ما به روز شد بیایید به آدرس آن نگاهی بیندازیم: "… / index.php؟ OrderName = Test & count = 12". (در قسمت اول کلمه "Test" را در "12" دوم تایپ کردم). همانطور که می بینیم آدرس صفحه کمی تغییر کرده است. واقعیت این است که انتقال پارامترها با درخواست GET با اختصاص دادن آنها به خط آدرس صفحه انجام می شود. پارامترها از آدرس اصلی با "؟" و پارامترهای مختلف با "&" جدا می شوند. ساختار پارامترها به شرح زیر است: پارامتر_نام = مقدار... نام پارامتر با مقدار ویژگی name در قسمت ورودی مطابقت دارد.
بیایید کد صفحه را کمی ویرایش کنیم:

> >

حالا بیایید دوباره بر روی دکمه "Order" کلیک کنیم. همانطور که می بینیم، صفحه به روز شده است، اما فیلدهای ما پر شده است. این به این دلیل است که ما یک مقدار پیش فرض برای فیلدهای خود تعیین کرده ایم. علاوه بر این، این مقادیر پارامتر GET دریافتی هستند. همانطور که در کد PHP می بینیم، پارامترهای GET یک آرایه با یک شاخص رشته ای برابر با نام پارامتر هستند. اگر اکنون با آدرس سایت بازی کنیم و مقادیر پارامترهای موجود در آن را تغییر دهیم و دکمه "Enter" را فشار دهیم، مجدداً متوجه تصویر با رفرش صفحه و پر کردن فرم خود خواهیم شد.

بدیهی است که ارسال اطلاعات مخفی یا خدماتی در یک درخواست GET اشتباه است (و ایمن نیست). بهتر است از آن برای انتقال مثلا id خبر استفاده کنید که باید از پایه گرفته شود یا نام صفحه ای که باید نمایش داده شود.

درخواست POST موضوع دیگری است. به همین ترتیب کار می کند، اما پارامترها را در نوار آدرس ذخیره نمی کند. بیایید شکل خود را تغییر دهیم:

$ _POST ["orderName"]?> > $ _POST ["count"]?> >

همانطور که می بینید، با این حال، چیز زیادی تغییر نکرده است! بیایید صفحه خود را باز کنیم، چیزی را در فیلدها قرار دهیم و دکمه "سفارش" را فشار دهیم. همه چیز به همین صورت کار می کرد، با این حال، همانطور که در خط پرس و جو می بینیم، آدرس "... / index.php" بدون هیچ گونه پارامتری خودنمایی می کند. بنابراین، ما به نوعی داده های خود را از چشمان کنجکاو "پنهان می کنیم". البته، این مفهوم پنهان بود، و نه دلخواه، زیرا این داده ها هنوز هم قابل رهگیری هستند، اما این داستان دیگری است. بیایید پارامترهای "… / index.php؟ OrderName = Trololo & count = 100" را به آدرس خود اضافه کرده و "Enter" را فشار دهید. همانطور که می بینیم، صفحه بارگذاری شده است، اما با وجود اینکه پارامترها ارسال شده اند، فیلدها خالی هستند. این نشان می دهد که با وجود شباهت زیاد، این نوع درخواست ها به هیچ وجه با هم همپوشانی ندارند و در صورت نیاز، ارزش آن را دارد که برای هر نوع درخواست جداگانه، یک handler بنویسید.

فکر می کنم همین کافی باشد. اصول اولیه سوال به نظر من با سر توضیح داده شده است.

و کمی بیشتر… بررسی پارامترهای تصویب شده را فراموش نکنید. اگر مطمئن هستید که پارامتر باید یک عدد باشد، تمام تلاش‌ها برای انتقال یک مقدار غیر عددی و غیره را قطع کنید.

ممکن است متوجه شده باشید که در اکثر سایت ها می توانید آدرس های زیر را مشاهده کنید:

Http: //site/index.php؟ وبلاگ = 2

در اینجا، حتی بدون دانستن php، می توانید حدس بزنید که ما به فایل اشاره می کنیم index.phpاما تعداد کمی از مردم می دانند که بعد از علامت سوال چه چیزی می آید. خیلی ساده است: وبلاگ = 2این اعلان متغیر جهانی "$ _GET [" blog "]" با مقدار "2" است. بنابراین، من یک متغیر را به اسکریپت ارسال می کنم که وظیفه نمایش اطلاعات از پایگاه داده را بر عهده دارد. بیایید یک اسکریپت کوچک بنویسیم که در آن همه چیز را به وضوح خواهید دید:

if (isset ($ _ GET ["blog"])) (
echo $ _GET ["blog"];
}
?>

ما از دستور شرط if () استفاده می کنیم زیرا شرط خط زیر است:

Isset ($ _ GET ["blog"])

isset () به شما امکان می دهد بفهمید متغیری که در پرانتز مشخص شده است وجود دارد یا خیر، یعنی شرایطی که در کد توضیح دادم به این صورت است: اگر متغیر $ _GET ["blog"] وجود دارد، محتویات را نمایش دهید. این متغیر روی صفحه نمایش این چیزی است که اتفاق افتاد:

من فکر می کنم واضح است که یک متغیر جهانی در حال ایجاد است $ _GETبا شناسه ای که در نوار آدرس اعلام کردیم ( در این مورد با شناسه "blog")

حالا می خواهم یک نکته را روشن کنم. فرض کنید باید دو متغیر را تعریف کنیم، چگونه این کار را انجام دهیم؟ اولین متغیر بعد از علامت سوال "?" اعلام می شود. متغیر دوم بعد از علامت "&" ( راستش من نمی دانم این نشانه چیستدر اینجا مثالی از اعلان سه متغیر آورده شده است:

Http: //site/index.php؟ A = 1 & b = 2 & c = 3

این هم کد خروجی:

if (isset ($ _ GET ["a"]) AND isset ($ _ GET ["b"]) AND isset ($ _ GET ["c"])) (
echo $ _GET ["a"]."
";
echo $ _GET ["b"]."
";
echo $ _GET ["c"]."
";
}
?>

شرایط به این صورت است:

اگر یک متغیر جهانی $ _GET ["a"] و یک متغیر جهانی $ _GET ["b"] و یک متغیر جهانی _GET $ ["c"] وجود دارد، آنها را نمایش دهید.، نتیجه این است:

تشکیل می دهد

قبل از اینکه به پستپرس و جو، شما باید بفهمید که چه اشکالی هستند؟ چرا لازم است؟ زیرا متغیر جهانی $ _POST [""] از طریق فرم ها ایجاد می شود. فرم چیست؟ اینها فیلدهایی برای وارد کردن نوعی اطلاعات توسط کاربر هستند. فیلدها در یک خط هستند، فیلدهای بزرگ، دکمه های رادیویی نیز وجود دارد، کادرهای بررسی. بیایید همه چیز را به ترتیب مرتب کنیم ...

فرم یک برچسب است:


عناصر شکل

فرم دارای ویژگی هایی است، من رایج ترین آنها را لیست می کنم:

بیایید یک فرم ایجاد کنیم:


عناصر شکل

به عنوان فایل کنترل کننده، فایل را قرار دادم test.phpهمانطور که در آن است که من نمونه هایی را برای شما می نویسم. من روش ارسال پست را تنظیم کردم زیرا این روش ها در 99.9٪ موارد استفاده می شود. من هم به فرم ما یک نام - فرم دادم

حالا بیایید به دنیای عناصر فرم شیرجه بزنیم. اولین چیزی که باید بدانید این است که تقریباً همه عناصر برچسب هستند. تنها تفاوت در صفت است نوعدر این برچسب ها اجازه دهید عناصر فرم استفاده شده را فهرست کنم:

من مطمئن هستم که شما بیش از یک بار چنین زمینه هایی را دیده اید، بنابراین در اینجا، همانطور که می گویند: "بدون نظر"

حال بیایید یک پرسشنامه آموزشی کوتاه گرد آوری کنیم که در ادامه با آن کار خواهیم کرد. وظیفه ما این است که یک پرسشنامه کوچک بسازیم که به ما می گوید نام فردی که پر کرده است، جنسیت، کشوری که او از کدام کشور است، رنگ مورد علاقه او و یک قسمت متنی که کاربر می تواند چیزی در مورد خودش اضافه کند. این کاری است که من انجام دادم:

نام خانوادگی شما نام و نام خانوادگی:

جنسیت شما:
م
اف

از کدام کشور هستی



رنگ (های) مورد علاقه:

مشکی:
قرمز:
سفید:
یکی دیگر:

در مورد خودم:




توجه داشته باشید که تقریباً هر برچسب دارای یک ویژگی است مقدار، این برای چیست؟ داده هایی را که قرار است به صفحه دیگری منتقل کنید را ثبت می کند. امیدوارم واضح باشد

حال اگر این کد را در مرورگر اجرا کنیم، موارد زیر را مشاهده خواهیم کرد:

من از ویژگی برای فرم استفاده کردم عملبا معنی test.phpیعنی همانطور که گفتم داده های فرم به فایل test.php منتقل می شود.

درخواست POST

حالا بیایید کد php بنویسیم که به ما امکان می دهد اطلاعات وارد شده را ببینیم. داده ها کجا ذخیره می شوند؟ در مورد درخواست دریافت، داده های ما در متغیر جهانی $ _GET [""] ذخیره می شود. هنگامی که یک درخواست ارسال ارسال می شود، داده ها در متغیر جهانی $ _POST [""] قرار می گیرند. در پرانتز، باید شناسه را بنویسید، مانند متغیر جهانی get. سوال اینجاست که این شناسه را از کجا می توانم تهیه کنم؟ به همین دلیل است که ما به ویژگی name در عناصر فرم نیاز داریم! این نام ها هستند که به عنوان کلید برای ما در پست آرایه جهانی عمل می کنند. خب، بیایید شروع به توصیف فیلمنامه کنیم:

if (isset ($ _ POST ["ارسال"])) (
echo "Name:". $ _ POST ["fio"]."
";
echo "Sex:". $ _ POST ["sex"]."
";
echo "کشور محل اقامت:". $ _ POST ["شهر"]."
";

اکو "رنگ (های) مورد علاقه:
";
echo $ _POST ["color_1"]."
";
echo $ _POST ["color_2"]."
";
echo $ _POST ["color_3"]."
";
echo $ _POST ["color_4"]."
";
echo "درباره من:". $ _ POST ["درباره"]."


";
}
?>

شرط if که نوشته ایم می گوید: اگر یک متغیر جهانی $ _POST ["submit"] وجود داشته باشد، داده ها را روی صفحه نمایش می دهیم. اگر روی دکمه ارسال کلیک کنیم این متغیر سراسری ایجاد می شود، به همین دلیل در این مثال به ویژگی name در دکمه نیاز داریم. شاید تعجب کنید که چرا ویژگی name برای دکمه اختیاری است؟ خیلی ساده است. معمولاً برنامه نویس فشار دادن دکمه را ردیابی نمی کند، بلکه داده های ارسال شده را ردیابی می کند. برای عملکرد صحیح مثلاً فرم های تماس، لازم است نه فشار دادن یک دکمه، بلکه صحت اطلاعات وارد شده را ردیابی کنید و متوجه شوید که آیا اصلاً این اطلاعات وارد شده است یا خیر. در مثال خود، ما داده های ارسال شده را بررسی نکردیم، بلکه فقط کلیک دکمه را دنبال کردیم تا مثال را ساده کنیم ... آنچه به دست آوردیم این است:

نتیجه

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

PS: آیا می خواهید بازی های رایانه ای حتی واقعی تر شوند؟ Directx 11 برای ویندوز 7 را می توان به صورت رایگان در ویندوز دانلود کرد! از گرافیک عالی لذت ببرید!

مقالات مرتبط برتر