У дома / Разни / Как get работи в http. Заявки за публикуване и получаване, каква е разликата между тях и кое е по-добро и за какви цели? HTTP протокол. Въведение

Как get работи в http. Заявки за публикуване и получаване, каква е разликата между тях и кое е по-добро и за какви цели? HTTP протокол. Въведение

Този и следващите раздели ще покажат накратко как да създавате основни уеб приложения с помощта на PHP. Това, което беше обсъдено в раздела, очевидно не е достатъчно, за да може вашето приложение да комуникира с потребителя и да формулира в зависимост от действията, които е извършил или въведените от него параметри. какво липсва Няма достатъчно знания как да се организира въвеждането на потребителски данни и прехвърлянето им към сървъра. Е, вече трябва да имате основни познания за това как програмно да обработвате информацията, получена на сървъра.

Методи за HTTP заявка и техните параметри

Всяко динамично уеб приложение генерира отговор към потребителя в съответствие с въведените от него параметри или действията, извършени от страна на клиента. Свързването със сървъра най-често се свежда до два вида заявки: използване на метода GET или метода POST. Няколко думи за разликите между тези два вида заявки.

Метод GET:

    Параметрите се предават в заглавката на HTTP заявката, така че са видими в командна линия, и такава заявка може да бъде запазена в отметки. Тъй като общата дължина на заглавката е ограничена, броят и дължината на параметрите, предадени чрез GET, също са ограничени.

    Смята се, че резултатите от няколко идентични GET заявки, изпълнени подред, трябва да бъдат еднакви.

POST метод:

    Параметрите на заявката се предават в тялото на HTTP заявката, така че не присъстват в командния ред. Броят и размерът на параметрите е неограничен.

    Смята се, че резултатите от множество идентични POST заявки могат да върнат различни стойности, тъй като могат да променят свойствата на целевия обект.

Методът GET трябва да се използва за извличане на съдържанието на информационен ресурс според параметри, когато не е необходимо да се правят промени в структурите на данни на целевия ресурс и има смисъл заявката (URL) да се запазва в отметки. Методът GET може да е по-бърз от подобни заявки, използващи метода POST.

Методът POST трябва да се използва, когато трябва да скриете параметрите, предадени на сървъра от URL адреса. Този метод трябва да се използва и при заявки за промени в съдържанието на целевия ресурс, като се предава описание на тези промени в параметрите (в тялото на заявката).

Път до ресурс?parameter1=value1¶meter2=value2&…

Ако нямате специална HTML форма за попълване на параметри, тогава можете да отстраните грешки във вашето PHP приложение, като подадете тестови параметри директно в командния ред на браузъра, например:

Http://site/php-samples/sql.php?sql=select * от d_staff

За достъп до параметрите на заявката от страната на сървъра трябва да използвате глобални масиви $_GETИ $_POSTсъответно. Ако вашето приложение не се интересува от кой метод е достъпно, тогава трябва да използвате масив $_REQUEST, който комбинира данните от масивите $_GET и $_POST, например по този начин:

$sql = isset($_REQUEST["sql"])? $_REQUEST["sql"] : "";

В този пример програмата определя дали параметърът “sql” е предаден: ако да, тя присвоява стойността си на съответната променлива, а ако не, присвоява празна стойност.

Дефиниране на параметри на HTTP заявка чрез HTML форма

Разбира се, дефинирането на параметри ръчно директно в командния ред на браузъра не е много удобно. Този метод е подходящ за програмно изпълнение на HTTP заявки, когато уеб приложенията комуникират помежду си. За да въведете и извършите първоначална проверка на данните от страна на клиента, трябва да използвате HTML форми и . По-долу е даден пример най-простата форма, с който се въвежда текстов параметър (стойност), който впоследствие се предава на сървъра като параметър на метода POST.

метод ="пост" действие =’sql.php’ > SQL:

Атрибутът на метода на елемента на формуляра указва метода, който определя метода за предаване на данни към сървъра (get или post). Атрибутът за действие указва php файл , който ще обработи заявката. Ако манипулаторът трябва да бъде текущият файл, тогава атрибутът за действие не е необходимо да се добавя. За всички елементи, чиято стойност трябва да бъде предадена като параметър на HTTP заявка, трябва да дефинирате уникална стойност за атрибута name. Това е стойността на атрибута имеще бъде индексв масивите $_GET, $_POST или $_REQUEST (вижте примера по-горе). Натискане на бутон Изпращанеизпраща формата с всички въведени стойности на сървъра.

Първият метод за изпълнение на PHP POST заявка е да използвате file_get_contents. Вторият метод ще използва fread в комбинация с няколко други функции. И двете опции използват функцията stream_context_create за попълване на задължителните полета на заглавката на заявката.

Обяснение на кода

Променливата $sPD съдържа данните за прехвърляне. Трябва да е във формат на низ на HTTP заявка, така че някои специални знаци трябва да бъдат кодирани.

Както във функцията file_get_contents, така и във функцията fread имаме два нови параметъра. Първият е use_include_path. Тъй като правим HTTP заявка, тя ще бъде невярна и в двата примера. Когато е зададено на true за четене на локален ресурс, функцията ще търси файла в include_path.

Вторият параметър е контекст, който се попълва с върнатата стойност на stream_context_create, която приема стойността на $aHTTP масива.

Използване на file_get_contents за правене на POST заявки

За да изпратите POST заявка с помощта на file_get_contents в PHP, трябва да използвате stream_context_create, за да попълните ръчно полетата на заглавката и да посочите коя „обвивка“ да използвате - в в такъв случай HTTP:

$sURL = "http://brugbart.com/Examples/http-post.php"; // POST URL $sPD = "name=Jacob&bench=150"; // POST данни $aHTTP = array("http" => // Обвивка, която ще се използва array("method" => "POST", // Метод на заявка // Заглавките на заявките са зададени под "header" => "Content" - тип: application/x-www-form-urlencoded", "content" => $sPD)); $context = stream_context_create($aHTTP); $contents = file_get_contents($sURL, false, $context); ехо $съдържание;

Използване на fread за изпълнение на POST заявки

Можете да използвате функцията fread, за да правите POST заявки. Следващият пример използва stream_context_create за съставяне на необходимите заглавки на HTTP заявка:

$sURL = "http://brugbart.com/Примери/http-post.php"; // POST URL $sPD = "name=Jacob&bench=150"; // POST данни $aHTTP = array("http" => // Обвивка, която ще се използва array("method" => "POST", // Метод на заявка // Заглавките на заявките са зададени под "header" => "Content" - тип: application/x-www-form-urlencoded", "content" => $sPD)); $context = stream_context_create($aHTTP); $handle = fopen($sURL, "r", false, $context); $съдържание = ""; докато (!feof($handle)) ( $contents .= fread($handle, 8192); ) fclose($handle); ехо $съдържание;

Правене на GET заявки с PHP

Сега ще се съсредоточим върху използването на fread и file_get_contents за изтегляне на съдържание от интернет чрез HTTP и HTTPS. За да използвате методите, описани в тази статия, трябва да активирате опцията fopen wrappers. За да направите това, трябва да зададете параметъра allow_url_fopen на On във файла php.ini.

Изпълнението на POST и GET заявки в PHP се използва за влизане в уебсайтове, извличане на съдържание на уеб страници или проверка за нови версии на приложения. Ще разгледаме как да правите прости HTTP заявки.

Използване на fread за изтегляне или получаване на файлове през интернет

Не забравяйте, че четенето на уеб страници е ограничено до достъпната част на пакета. Така че трябва да използвате функцията stream_get_contents ( подобно на file_get_contents) или цикъл while за четене на съдържанието на по-малки парчета, докато се достигне краят на файла:

В този случай на обработка на PHP POST заявка, последният аргумент на функцията fread е равен на размера на фрагмента. Обикновено не трябва да е по-голямо от 8192 ( 8*1024 ).

Общото между тях е, че работят по един и същ начин. Технически няма разлика между тях. Но има идеологически различия.

Ще говоря за тях в контекста на PHP. Моля, обърнете внимание, че HTTP протоколът е косвено свързан с PHP, защото е създаден за обмен на html страници и PHP просто разширява възможностите и на двата.

Заявката GET се използва за получаване на данни, а POST се използва за изпращане. (Не забравяйте, че технически те работят по същия начин).

Следователно, в контекста на PHP, въз основа на тази идеология, направихме следното:
1. Всеки път, когато стартирате PHP, суперглобалните масиви ($_GET, $_POST) се създават по подразбиране.
2. Ако има въпросителен знак (?) в низа на заявката. Всичко след него се обмисля параметри GET заявка те се представят във формат "ключ"="стойност" и знакът амперсанд (&) се използва като разделител.
Пример:
GET /index.php?name=Andrey&surname=Galkin
Това е низ за заявка, има 2 параметъра. тези параметри ще отидат в масива $_GET.
3. $_POST се попълва по различен начин. съдържанието на този масив се попълва от "заглавките на заявките". Тоест от място, което е ясно скрито от погледа. Браузърът се грижи за цялата работа по създаването на такива заглавки. Въпреки че понякога нещо се редактира ръчно в заглавията.

Най-често заявката за публикуване се използва във формуляри (за изпращане на данни).

Например, имаме форма за вход с 2 полета: потребителско име и парола.

Нека си представим, че използваме метода GET. След това, когато изпращаме формуляра, ще отидем на следния адрес /login.php?login=Andrey&password=123 Съгласете се, че предаването на такава информация по този начин не е никак безопасно. Всеки може да отвори вашия браузър и като започне да въвежда адреса на сайта, може да види вашите пароли и влизания от хронологията.

Но ако посочим метода POST, ще получим следната заявка:
POST /login.php (login=Andrey&password=123) това, което е в скоби, ще бъде скрито и няма да бъде запазено по никакъв начин в браузъра.

Да го обобщим:
GET е да получите конкретна страница определена форма(сортиране, текуща страницаблог, лента за търсене и др.).
POST - за изпращане на данни, които не засягат показването на страницата, в смисъл, че тези данни засягат само резултата от скрипта (влизане, пароли, номера на кредитни карти, съобщения и др.).

И още една добра новина е, че могат да се комбинират напр
POST /index.php?page=login (login=Andrey&password=123) Мисля, че вече обясних достатъчно какво ще излезе от това и кои параметри ще влязат в кой масив.

IN напоследъкВсе по-често срещам въпроси в главния форум на PHPClub по темата за създаване на POST и GET заявки, както и въпроси по темата: „Как мога да генерирам POST заявка с помощта на функцията за заглавие.“ Вярвам, че необходимостта от поставяне на точка „i“ в използването на тази технология, тъй като начинаещите програмисти просто не разбират принципите на мрежата като такива. И така, нека започнем нашето пътуване из света на HTTP протокола.

1. HTTP протокол. Въведение

Бих искал веднага да изясня едно малко нещо. Ужасният протокол на думата не е нищо повече от споразумение на много хора, просто в един прекрасен момент хората решиха: „Нека го направим по този начин и тогава всичко ще бъде наред.“ Няма от какво да се страхуваме, всичко е просто скандално и сега ще разкрием този позор. И така, какво е HTTP протоколът и за какво се използва?

1.1 Клиент и сървър

Няма чудеса в света и особено в света на програмирането и интернет! Приемете това като непоклатима истина. И ако програмата не работи или не работи както желаете, тогава най-вероятно тя е написана неправилно или съдържа грешки. И така, как браузърът иска от сървъра да му изпрати нещо? Да, много просто! Просто трябва да се отпуснете малко и да започнете да се наслаждавате на процеса :-)

1.2. Пишем първата си HTTP заявка

Ако мислите, че всичко е твърде сложно, тогава грешите. Човекът е устроен по такъв начин, че просто не е в състояние да създаде нещо сложно, в противен случай той самият ще се обърка в него :-) И така, има браузър и има уеб сървър. Браузърът винаги е инициатор на обмена на данни. Уеб сървърът никога няма просто да изпрати нещо на някого, така че да изпрати нещо на браузъра - браузърът трябва да го поиска. Най-простата HTTP заявка може да изглежда така:

ВЗЕМЕТЕ http://www.php.net/ HTTP/1.0\r\n\r\n

  • GET (в превод от английски означава „получаване“) - вид заявка; типът заявка може да бъде различен, например POST, HEAD, PUT, DELETE (ще разгледаме някои от тях по-долу).
  • http://www.php.net/ - URI (адрес), от който искаме да получим поне малко информация (естествено, надяваме се да научим HTML страницата).
  • HTTP/1.0 е типът и версията на протокола, който ще използваме при комуникация със сървъра.
  • \r\n е краят на реда, който трябва да се повтори два пъти; защо ще стане ясно малко по-късно.
Можете да изпълните тази заявка много просто. Стартирайте програмата telnet.exe, въведете www.php.net като хост, посочете порт 80 и просто въведете тази заявка, като натиснете Enter два пъти \r\n\r\n. В отговор ще получите HTML код начална страницасайт www.php.net.

1.3 Структура на заявката

Нека да разгледаме от какво се състои една HTTP заявка. Всичко е съвсем просто. Нека започнем с факта, че HTTP заявката е напълно смислен текст. В какво се състои в общия случай? Ще разгледаме протокола HTTP 1.0. Така:

Линия за заявка [Общо-заглавие | Заглавка на заявката | Заглавка на обект ]\r\n[ Тяло на обект ]

  • Линия за заявка- низ за заявка
  • Формат: "Метод Заявка-URI HTTP-версия\r\n"

  • Метод- Методът, по който ще се обработва Request-URI ресурсът, може да бъде GET, POST, PUT, DELETE или HEAD.
  • Заявка-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".

  • Общо-заглавие- основната част на заглавието.
    формат:
    Може да има само два параметъра: дата или прагма. Дата - дата по Гринуич във формат "Ден от седмицата, ден месец година HH:MM:SS GMT", например "Tue, 15 Nov 1994 08:12:31 GMT" - дата на създаване на заявката. Pragma може да има една стойност без кеш, която деактивира кеширането на страницата.
  • Заглавие на заявката- част от заглавката, която описва заявката.

    Заглавката на заявката може да има следните параметри: Разрешаване, Упълномощаване, От, Ако е променено от, Референт, Потребителски агент.
    В тази глава няма да разглеждаме параметъра Authorization, тъй като той се използва за достъп до частни ресурси, което не е необходимо много често. Можете да научите как сами да създадете заглавка за оторизиран достъп на www.w3c.org.

  • Позволява- задава приемливи методи за обработка.
    Формат: "Разрешаване: GET | HEAD\n".
    Параметърът се игнорира при указване на метода за POST обработка в Request-Line. Указва приемливи методи за обработка на заявки. Прокси сървърите не променят параметъра Allow и той достига до сървъра непроменен.
  • от - имейл адрескойто е изпратил заявката.
    Формат: "От: adderss\r\n".
    Например „От: [имейл защитен]\r\n".
  • If-Modified-Since- показва, че заявката не е променяна от такъв и такъв момент.
    Формат: "Ако-променено-от: дата\r\n"
    Използва се само за метода на обработка GET. Датата се посочва в GMT в същия формат като за параметъра Date в General-Header.
  • Референт- абсолютна връзка към страницата, от която е инициирана заявката, т.е. връзка към страницата, от която потребителят е стигнал до нашата.
    Формат: „Препращащ адрес: url\n“.
    Пример: „Препращащ адрес: www.host.ru/index.html\n“.
  • Потребителски агент- тип браузър.
    Например: „Потребителски агент: Mozilla/4.0\n“
  • Entity-Header- част от заглавката, описваща данните за обект-тяло.
    Тази част от заявката указва параметри, които описват тялото на страницата. Entity-Header може да съдържа следните параметри: Allow, Content-Encoding, Content-Length, Content-Type, Expires, Last-Modified, extension-header.
  • Позволява- параметър, подобен на Allow from General-Header.
  • Кодиране на съдържанието- тип кодиране на данни Entity-Body.
    Формат: "Кодиране на съдържание: x-gzip | x-compress | друг тип\n".
    Пример: „Кодиране на съдържание: x-gzip\n“. Символът "|". означава думата „или“, тоест това или онова или онова и т.н.
    Друг тип може да показва как се кодират данните, например за метода POST: „Content-Encoding: application/x-www-form-urlencoded\n“.
  • Съдържание-дължина- броя на байтовете, изпратени до тялото на обекта. Стойността Content-Length има съвсем различно значение за данни, изпратени във формат MIME, където действа като параметър за описание на част от данните - "external/entity-body". Валидни числа са цели числа от нула нагоре.
    Пример: "Дължина на съдържанието: 26457\n".
  • Тип съдържание- вид на предаваните данни.
    Например: "Content-Type: text/html\n".
  • Изтича- Времето, когато страницата трябва да бъде премахната от кеша на браузъра.
    Формат: „Изтича: дата\n“. Форматът на датата е същият като формата на датата за параметъра Date от General-Header.
  • Последно модифициран- време на последната промяна на предадените данни.
    Формат: „Последна промяна: дата\n“. Форматът на датата е същият като формата на датата за параметъра Date от General-Header.
  • разширение-заглавие- част от заглавката, която може да бъде предназначена например за обработка от браузър или друга програма, която получава документа. В тази част можете да опишете вашите параметри във формата „Име на параметър: стойност на параметър\n“. Тези параметри ще бъдат игнорирани, ако клиентската програма не знае как да ги обработи.
    Например: "Cookie: r=1\r\n" - задава добре познати бисквитки за страницата.

И сега, след такива ужасни думи, нека се опитаме да се успокоим малко и да разберем от какво имаме нужда? Разбира се, ще разберем с примери.

Нека си представим, че трябва да получим страница от сайта чрез предаване на бисквитки, в противен случай просто ще бъдем изпратени като неканени гости и освен това е известно, че ви е разрешен достъп до тази страница само след като сте посетили главната страница на сайт.

2 GET метод

Нека напишем нашата молба.

ВЗЕМЕТЕ http://www.site.ru/news.html HTTP/1.0\r\n
Хост: www.site.ru\r\n

Бисквитка: доход=1\r\n
\r\n

Тази заявка ни казва, че искаме да получим съдържанието на страницата на http://www.site.ru/news.html с помощта на метода GET. Полето Host показва, че тази страница се намира на сървъра www.site.ru, полето Referer показва, че сме дошли за новини от главната страница на сайта, а полето Cookie показва, че ни е назначена такава и такава бисквитка. Защо полетата Host, Referer и Cookie са толкова важни? Тъй като нормалните програмисти, когато създават динамични сайтове, проверяват полетата с данни, които се появяват в скриптове (включително PHP) под формата на променливи. За какво е това? За да не бъде например обектът ограбен, т.е. не са задали програма за автоматично изтегляне или така че човек, който посещава сайта, винаги да стига до него само от главната страница и т.н.

Сега нека си представим, че трябва да попълним полетата на формуляра на страницата и да изпратим заявка от формуляра, нека в този формуляр има две полета: вход и парола (вход и парола) - и, разбира се, знаем входа и парола.

ВЗЕМЕТЕ http://www.site.ru/news.html?login=Petya%20Vasechkin&password=qq HTTP/1.0\r\n
Хост: www.site.ru\r\n
Референт: http://www.site.ru/index.html\r\n
Бисквитка: доход=1\r\n
\r\n

Входът ни е "Петя Васечкин" Защо трябва да пишем Петя%20Васечкин? Това е така, защото специалните символи могат да бъдат разпознати от сървъра като признаци за наличие на нов параметър или край на заявка и т.н. Следователно има алгоритъм за кодиране на имена на параметри и техните стойности, за да се избегнат ситуации на грешка в заявката. Пълно описаниена този алгоритъм може да се намери, а в PHP има функции rawurlencode и rawurldecode съответно за кодиране и декодиране. Бих искал да отбележа, че PHP извършва декодирането сам, ако в заявката са предадени кодирани параметри. С това приключвам първата глава от моето запознанство с HTTP протокола. В следващата глава ще разгледаме заявки за изграждане като POST (преведено от английски като „изпращане“), което ще бъде много по-интересно, т.к. Това е типът заявка, която се използва при изпращане на данни от HTML формуляри.

3. POST метод.

В случай на HTTP POST заявка има две опции за прехвърляне на полета от HTML формуляри, а именно използване на алгоритъма application/x-www-form-urlencoded и multipart/form-data. Разликите между тези алгоритми са доста значителни. Факт е, че първият тип алгоритъм е създаден отдавна, когато езикът HTML все още не е предвиждал възможност за прехвърляне на файлове чрез HTML формуляри. И така, нека разгледаме тези алгоритми с примери.

3.1 Content-Type: application/x-www-form-urlencoded.

Пишем заявка, подобна на нашата GET заявка за прехвърляне на потребителско име и парола, която беше обсъдена в предишната глава:


Хост: www.site.ru\r\n
Референт: http://www.site.ru/index.html\r\n
Бисквитка: доход=1\r\n
Content-Type: application/x-www-form-urlencoded\r\n
Дължина на съдържанието: 35\r\n
\r\n

Тук виждаме пример за използване на полетата за заглавка Content-Type и Content-Length. Content-Length казва колко байта ще заема областта с данни, която е отделена от заглавката с друг нов ред \r\n. Но параметрите, които преди бяха поставени в Request-URI за GET заявка, сега са в Entity-Body. Вижда се, че се образуват по абсолютно същия начин, само трябва да ги напишете след заглавието. Искам да отбележа още нещо важен момент, нищо не пречи, едновременно с набора от параметри в Entity-Body, да се поставят параметри с други имена в Request-URI, например:

ПУБЛИКУВАЙТЕ http://www.site.ru/news.html?type=user HTTP/1.0\r\n
.....
\r\n
вход=Петя%20Васечкин&парола=qq

3.2 Content-Type: multipart/form-data

Веднага след като светът на Интернет разбра, че би било хубаво да се изпращат файлове чрез формуляри, консорциумът на W3C се зае с прецизиране на формата на POST заявка. По това време форматът MIME (Multipurpose Internet Mail Extensions - многофункционални разширения на протокол за генериране на имейл съобщения) вече беше широко използван, следователно, за да не изобретяваме колелото, решихме да използваме част от този формат за генериране на съобщения, за да създадем POST заявки в HTTP протокола.

Какви са основните разлики между този формат и типа application/x-www-form-urlencoded?

Основната разлика е, че Entity-Body вече може да бъде разделен на секции, които са разделени от граници (граница). Най-интересното е, че всяка секция може да има собствен хедър, който да описва данните, които се съхраняват в нея, т.е. в една заявка можете да прехвърляте данни от различни типове (както в Mail писмо, можете да прехвърляте файлове едновременно с текст).

Така че да започваме. Нека разгледаме отново същия пример с прехвърлянето на потребителско име и парола, но сега в нов формат.

ПУБЛИКУВАЙТЕ http://www.site.ru/news.html HTTP/1.0\r\n
Хост: www.site.ru\r\n
Референт: http://www.site.ru/index.html\r\n
Бисквитка: доход=1\r\n

Дължина на съдържанието: 209\r\n
\r\n
--1BEF0A57BE110FD467A \r\n
Съдържание-Диспозиция: форма-данни; име="вход" \r\n
\r\n
Петя Васечкин \r\n
--1BEF0A57BE110FD467A \r\n
Съдържание-Диспозиция: форма-данни; име="парола" \r\n
\r\n
qq \r\n
--1BEF0A57BE110FD467A-- \r\n

Сега да разберем написаното. :-) Специално подчертах някои символи \r\n с удебелен шрифт, за да не се сливат с данните. Ако се вгледате внимателно, ще забележите граничното поле след Content-Type. В това поле се указва разделителят на секции - граница. Като граница може да се използва низ, състоящ се от латински букви и цифри, както и някои други символи (за съжаление, не помня кои други). В тялото на заявката „--“ се добавя към началото на границата и заявката завършва с граница, към която също се добавят знаците „--“ в края. Нашата заявка има два раздела, първият описва полето за вход, а вторият описва полето за парола. Content-Disposition (типът данни в секцията) казва, че това ще бъдат данни от формуляра, а полето за име указва името на полето. Тук завършва заглавката на раздела и това, което следва, е областта с данни на раздела, в която се поставя стойността на полето (няма нужда да кодирате стойността!).

Бих искал да обърна внимание на факта, че не е необходимо да използвате Content-Length в заглавките на секциите, но в заглавката на заявката трябва и стойността му е размерът на цялото тяло на обекта, което се появява след втория \ r\n следваща дължина на съдържанието: 209\ r\n. Тези. Тялото на обекта е отделено от заглавката с допълнителен нов ред (който също може да се види в секции).

Сега нека напишем заявка за прехвърляне на файл.

ПУБЛИКУВАЙТЕ http://www.site.ru/postnews.html HTTP/1.0\r\n
Хост: www.site.ru\r\n
Референт: http://www.site.ru/news.html\r\n
Бисквитка: доход=1\r\n
Content-Type: multipart/form-data; граница=1BEF0A57BE110FD467A\r\n
Дължина на съдържанието: 491\r\n
\r\n
--1BEF0A57BE110FD467A \r\n
Съдържание-Диспозиция: форма-данни; name="news_header" \r\n
\r\n
Примерни новини \r\n
--1BEF0A57BE110FD467A \r\n
Съдържание-Диспозиция: форма-данни; име="файл_новини"; име на файл="news.txt" \r\n
Content-Type: приложение/октет-поток \r\n
Кодиране на прехвърляне на съдържание: двоично \r\n
\r\n
А ето я и новината, която е във файла news.txt \r\n
--1BEF0A57BE110FD467A-- \r\n

В този пример първата секция изпраща заглавието на новината, а втората секция изпраща файла news.txt. Ако сте внимателни, ще видите полетата за име на файл и Content-Type във втория раздел. Полето за име на файл указва името на файла, който се изпраща, а полето Content-Type указва типа на този файл. Application/octet-stream показва, че това е стандартен поток от данни, а Content-Transfer-Encoding: binary показва, че това са двоични данни, които не са кодирани по никакъв начин.

Много важен момент. Повечето CGI скриптове са написани от умни хора, така че те обичат да проверяват типа на входящия файл, който е в Content-Type. За какво? Най-често качването на файлове в уебсайтове се използва за получаване на изображения от посетителя. И така, самият браузър се опитва да определи какъв вид файл иска да изпрати посетителят и вмъква подходящия Content-Type в заявката. Скриптът го проверява при получаване и, например, ако не е gif или jpeg, той игнорира този файл. Следователно, когато създавате заявка „ръчно“, внимавайте за стойността Content-Type, така че да е най-близо до формата на прехвърления файл.

В нашия пример се генерира заявка, в която текстов файл. По същия начин се генерира заявка за прехвърляне на двоичен файл.

4. Послепис.

Мисля, че не си струва да говорим подробно за изпращането на заявки до сървъра. Това е въпрос на чисто RHP технология :-). Достатъчно е внимателно да прочетете раздела за функциите за работа със сокети или за функциите на модула CURL в официалната документация на PHP.

От горното се надявам, че сега е ясно защо въпросът е: „Как мога да генерирам POST заявка с помощта на функцията за заглавие?“ - безсмислено. Функцията header(string) добавя запис само към заглавката на заявката, но не и към тялото на заявката.

Има и друг тип заявка - Content-Type: multipart/mixed, надявам се, след като прочетете тази статия, лесно ще разберете този тип сами. Можете да го проучите подробно

Тази публикация е отговор на въпрос, зададен в една от моите статии.

В тази статия искам да ви кажа какво представляват HTTP методите GET/POST/PUT/DELETE и други, защо са измислени и как да ги използвате в съответствие с REST.

HTTP

И така, кой е един от основните протоколи на Интернет? Ще изпратя педантите на RFC2616, а останалите ще кажа човешки :)

Този протокол описва взаимодействието между два компютъра (клиент и сървър), изградено на базата на съобщения, наречени заявка (Request) и отговор (Response). Всяко съобщение се състои от три части: начален ред, заглавки и тяло. В този случай е необходима само началната линия.

Началните редове за заявката и отговора имат различни формати - интересуваме се само от началния ред на заявката, който изглежда така:

URI адрес на МЕТОДА HTTP/ ВЕРСИЯ ,

Където METHOD е методът на HTTP заявката, URI е идентификаторът на ресурса, VERSION е версията на протокола (за този моментверсия 1.1 е актуална).

Заглавките са колекция от двойки име-стойност, разделени с двоеточие. Заглавките предават различна служебна информация: кодиране на съобщението, име и версия на браузъра, адрес, от който е дошъл клиентът (референт) и т.н.

Тялото на съобщението е действително предаваните данни. В отговора предаваните данни по правило са HTML страницата, поискана от браузъра, а в заявката, например в тялото на съобщението, се предава съдържанието на файловете, качени на сървъра. Но като правило в заявката изобщо няма тяло на съобщението.

Пример за HTTP взаимодействие

Нека разгледаме един пример.

Заявка:
GET /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 Език на съдържанието: ru Тип съдържание: текст/html; charset=utf-8 Дължина на съдържанието: 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 (REpresentational State Transfer) е термин, въведен през 2000 г. от Рой Филдинг, един от разработчиците на HTTP протокола, като име на група принципи за изграждане на уеб приложения. Като цяло REST покрива по-широка област от HTTP - може да се използва и в други мрежи с други протоколи. REST описва принципите на взаимодействие между клиент и сървър, базирани на понятията „ресурс“ и „глагол“ (може да се разбира като субект и предикат). В случай на HTTP, ресурсът се идентифицира чрез неговия URI, а глаголът е HTTP методът.

REST предлага изоставяне на използването на един и същ URI за различни ресурси (т.е. адресите на две различни статии като /index.php?article_id=10 и /index.php?article_id=20 - това не е REST-way) и използване на различни 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 frameworks са направени с помощта на Rack), можете да добавите скрито поле към формуляра с името "_method" и укажете името на метода като стойност (напр. „PUT“) – в този случай ще бъде изпратена POST заявка, но Rack ще може да се престори, че е получил PUT, а не POST.