Формирование http запроса. Как отправить post запрос из браузера: метод пост. Учимся работать с GET и POST запросами
HTTP запрос, или сообщение состоит из трех частей: строки запроса, и тела HTTP сообщения.
Строка запроса
, или стартовая строка: в запросе к серверу — строка, которая содержит тип запроса (метод), URI запрашиваемой страницы, и версия (например HTTP/1.1). В ответе от сервера эта строка содержит версию HTTP протокола, и код ответа. Код ответа представляет собой целое число из трех цифр. За ним обычно следует отделённая пробелом поясняющая фраза, поясняющая код, например: 200 OK, или 404 Not Found.
Методы (типы) HTTP запроса
: GET, POST, PUT, PATCH, HEAD, DELETE, TRACE. Чаще всего в HTTP запросе используются методы GET, или POST: GET — используется для запроса содержимого web-страницы по указанному URI. URI — это адрес страницы без указания , например: /internet/chto-takoe-http-zapros-soobshhenie/ вместо сайт/internet/chto-takoe-http-zapros-soobshhenie/. Браузер может передавать параметры в GET в URI после символа « ? »: GET /index.php?param1=value1¶m2=value2. Кроме обычного метода GET, различают ещё условный GET и частичный GET. Условные запросы GET содержат заголовки If-Modified-Since , If-Match , If-Range и подобные.
POST — используется для отправки информации, на . При отправке данных методом POST, они указываются в теле HTTP сообщения, а не в строке ввода адреса в браузере, как это делается при передаче данных методом GET. Например, при отправке комментария через форму, которая расположена под статьей, информация на сервер передается именно методом POST. Так же с помощью метода POST загружают файлы на сервер.
— это часть запроса, в котором содержатся различные параметры, которые используются для правильного построения web-страницы.
Тело HTTP сообщения
— содержит полученные от сервера данные, например сформированную web-страницу в виде HTML кода, либо ресурс, например картинку.
Пример HTTP сообщений:
HTTP запрос к серверу:
GET /internet/chto-takoe-http-zapros-soobshhenie/ HTTP/1..9,image/webp,*/*;q=0.8
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/40.0.2150.0
Accept-Encoding: gzip, deflate, sdch
Accept-Language: ru-RU,ru;q=0.8,en-US;q=0.6,en;q=0.4
Cookie: wp-settings-1=hidetb%3D; wp-settings-time-1=1424958215; wordpress_test_cookie=WP+Cookie;
Ответ от сервера:
HTTP/1.1 200 OK - стартовая строка ответа
:
Server: nginx/1.6.2
Date: Sun, 19 Apr 2015 00:22:50 GMT
Content-Type: text/html; charset=UTF-8
Content-Length: 9431
Connection: keep-alive
Keep-Alive: timeout=30
X-Powered-By: PHP/5.5.22
Expires: Wed, 11 Jan 1984 05:00:00 GMT
Cache-Control: no-cache, must-revalidate, max-age=0
Pragma: no-cache
Vary: Accept-Encoding
Content-Encoding: gzip
Далее следует тело ответа (страница в HTML).
Являетесь вы программистом или нет, вы видели его повсюду в Интернете. На данный момент в адресной строке браузера отображается нечто, что начинается с «http: //». Даже ваш первый скрипт Hello World отправил HTTP-header без вашего понимания. В этой статье мы собираемся узнать об основах HTTP-заголовков и о том, как их можно использовать в наших веб-приложениях.
Что такое HTTP Headers?
HTTP значит "Hypertext Transfer Protocol" (Протокол передачи гипертекста). Всемирная паутина использует этот протокол. Он был создан в начале 1990-х годов. Почти всё, что вы видите в вашем браузере, передаётся на ваш компьютер через HTTP. Например, когда вы открыли страницу этой статьи, ваш браузер отправил более 40 HTTP-запросов и получил HTTP-ответы для каждого из них.
Заголовки HTTP являются основной частью этих HTTP-запросов и ответов, и они несут информацию о браузере клиента, запрошенной странице, сервере и многом другом.
Пример
Когда вы вводите URL-адрес в адресной строке, ваш браузер отправляет HTTP-запрос, и он может выглядеть так:
GET /tutorials/other/top-20-mysql-best-practices/ HTTP/1.1
Host: net.tutsplus.com
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5 (.NET CLR 3.5.30729)
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive: 300
Connection: keep-alive
Cookie: PHPSESSID=r2t5uvjq435r4q7ib3vtdjq120
Pragma: no-cache
Cache-Control: no-cache
Первая строка - это "Request Line", которая содержит некоторую базовую информацию по запросу. Остальные - HTTP заголовки.
После этого запроса ваш браузер получает ответ HTTP, который может выглядеть так:
HTTP/1.x 200 OK
Transfer-Encoding: chunked
Date: Sat, 28 Nov 2009 04:36:25 GMT
Server: LiteSpeed
Connection: close
X-Powered-By: W3 Total Cache/0.8
Pragma: public
Expires: Sat, 28 Nov 2009 05:36:25 GMT
Etag: "pub1259380237;gz"
Cache-Control: max-age=3600, public
Content-Type: text/html; charset=UTF-8
Last-Modified: Sat, 28 Nov 2009 03:50:37 GMT
X-Pingback: http://net.tutsplus.com/xmlrpc.php
Content-Encoding: gzip
Vary: Accept-Encoding, Cookie, User-Agent
Top 20+ MySQL Best Practices - Nettuts+
Первая строка - это «Строка состояния», за которой следуют «HTTP-заголовки», до пустой строки. После этого начинается «содержимое» (в данном случае - HTML вывод).
Когда вы смотрите на исходный код веб-страницы в своём браузере, вы видите только часть HTML, а не заголовки HTTP, хотя они фактически были переданы вместе.
Эти HTTP-запросы также отправляются и принимаются для других вещей, таких как изображения, CSS-файлы, файлы JavaScript и т. д. Именно поэтому я сказал ранее, что ваш браузер отправил не менее 40 или более HTTP-запросов, поскольку вы загрузили только эту страницу статьи.
Теперь давайте рассмотрим структуру более подробно.
Как увидеть HTTP Headers
Для анализа HTTP-заголовков я использую следующие расширения Firefox:
![](https://i2.wp.com/cdn.tutsplus.com/net/uploads/legacy/511_http/firebug.png)
![](https://i0.wp.com/cdn.tutsplus.com/net/uploads/legacy/511_http/live_http.png)
Заголовки HTTP в запросах HTTP
Теперь мы рассмотрим некоторые из наиболее распространенных HTTP headers , найденных в HTTP requests.
Почти все эти заголовки можно найти в массиве $ _SERVER в PHP. Вы также можете использовать функцию getallheaders() для извлечения всех заголовков одновременно.
Host
HTTP-запрос отправляется на определенные IP-адреса. Но так как большинство серверов способны размещать несколько сайтов под одним IP, они должны знать, какое доменное имя ищет браузер.
Host: net.tutsplus.com
Это в основном имя host, включая домен и поддомен.
В PHP его можно найти, как $_SERVER["HTTP_HOST"] или $_SERVER["SERVER_NAME"].
User-Agent
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5 (.NET CLR 3.5.30729)
Этот заголовок может содержать несколько частей информации, таких как:
Именно так веб-сайты могут собирать определённую общую информацию о своих системах surfers. Например, они могут определить, использует ли surfer мобильный браузер и перенаправляет их на мобильную версию своего веб-сайта, который лучше работает с низким разрешением.
В PHP может быть выражен так: $_SERVER["HTTP_USER_AGENT"].
If (strstr($_SERVER["HTTP_USER_AGENT"],"MSIE 6")) {
echo "Please stop using IE6!";
}
Accept-Language
Accept-Language: en-us,en;q=0.5
Этот заголовок отображает настройки языка по умолчанию. Если сайт имеет разные языковые версии, он может перенаправить нового surfer на основе этих данных.
В PHP его можно найти так: $ _SERVER ["HTTP_ACCEPT_LANGUAGE"].
If (substr($_SERVER["HTTP_ACCEPT_LANGUAGE"], 0, 2) == "fr") {
header("Location: http://french.mydomain.com");
}
Accept-Encoding
Accept-Encoding: gzip,deflate
Большинство современных браузеров поддерживают gzip и отправляют это в header. Затем веб-сервер может отправить выходной HTML-код в сжатом формате. Это позволяет уменьшить размер до 80% для экономии пропускной способности и времени.
В PHP его можно найти так: $ _SERVER ["HTTP_ACCEPT_ENCODING"]. Однако, когда вы используете функцию обратного вызова ob_gzhandler() , она будет проверять значение автоматически, поэтому вам это не нужно.
// enables output buffering
// and all output is compressed if the browser supports it
ob_start("ob_gzhandler");
If-Modified-Since
Если веб-документ уже сохранен в кеше в браузере и вы посещаете его снова, ваш браузер может проверить, был ли документ обновлён, отправив следующее:
Если он не изменялся с этой даты, сервер отправляет код ответа «304 Not Modified», а содержимое - нет, и браузер загружает содержимое из cache.
В PHP его можно найти так: $ _SERVER ["HTTP_IF_MODIFIED_SINCE"].
// assume $last_modify_time was the last the output was updated
// did the browser send If-Modified-Since header?
if(isset($_SERVER["HTTP_IF_MODIFIED_SINCE"])) {
// if the browser cache matches the modify time
if ($last_modify_time == strtotime($_SERVER["HTTP_IF_MODIFIED_SINCE"])) {
// send a 304 header, and no content
header("HTTP/1.1 304 Not Modified");
exit;
}
}
Существует также HTTP-заголовок Etag, который можно использовать для проверки текущего кэша. Мы поговорим об этом в ближайшее время.
Cookie
Как следует из названия, это отправляет файлы cookie, хранящиеся в вашем браузере для этого домена.
Cookie: PHPSESSID=r2t5uvjq435r4q7ib3vtdjq120; foo=bar
Это пары name=value, разделённые точками с запятой. Cookies могут также содержать id сеанса.
В PHP отдельные cookie-файлы могут быть доступны с помощью массива $ _COOKIE. Вы можете напрямую обращаться к переменным сеанса, используя массив $ _SESSION, и если вам нужен id сеанса, вы можете использовать функцию session_id () вместо cookie.
Echo $_COOKIE["foo"];
// output: bar
echo $_COOKIE["PHPSESSID"];
// output: r2t5uvjq435r4q7ib3vtdjq120
session_start();
echo session_id();
// output: r2t5uvjq435r4q7ib3vtdjq120
Referer
Как следует из названия, этот HTTP header содержит ссылочный url.
Например, если я зашел на домашнюю страницу Nettuts + и нажал ссылку на статью, этот header будет отправлен в мой браузер:
Referer: http://net.tutsplus.com/
В PHP его можно найти как $ _SERVER ["HTTP_REFERER"].
If (isset($_SERVER["HTTP_REFERER"])) {
$url_info = parse_url($_SERVER["HTTP_REFERER"]);
// is the surfer coming from Google?
if ($url_info["host"] == "www.google.com") {
parse_str($url_info["query"], $vars);
echo "You searched on Google for this keyword: ". $vars["q"];
}
}
// if the referring url was:
// http://www.google.com/search?source=ig&hl=en&rlz=&=&q=http+headers&aq=f&oq=&aqi=g-p1g9
// the output will be:
// You searched on Google for this keyword: http headers
Возможно, вы заметили, что слово «referrer» написано с ошибкой, как «referer». К сожалению, он превратился в официальную спецификацию HTTP подобным образом и застрял.
Authorization
Authorization: Basic bXl1c2VyOm15cGFzcw==
Данные внутри header имеют кодировку base64. Например, base64_decode ("bXl1c2VyOm15cGFzcw ==") возвратит "myuser: mypass"
В PHP эти значения можно найти как $ _SERVER ["PHP_AUTH_USER"] и $ _SERVER ["PHP_AUTH_PW"].
Подробнее об этом будет, когда мы поговорим о заголовке WWW-Authenticate.
Заголовки HTTP в ответах HTTP
Теперь мы рассмотрим некоторые из наиболее распространенных HTTP headers, найденных в HTTP-ответах.
В PHP вы можете установить заголовки ответа, используя функцию header() . PHP уже отправляет определённые заголовки автоматически, для загрузки содержимого и настройки файлов cookie и прочее... Вы можете увидеть headers, которые отправляются или будут отправляться с помощью функции headers_list () . Вы можете проверить, были ли уже отправлены заголовки с помощью функции headers_sent() .
Cache-Control
Определение из w3.org: «Поле заголовка Cache-Control используется для указания директив, которые ДОЛЖНЫ выполняться всеми механизмами кэширования по цепочке запросов/ответов». Эти «механизмы кэширования» включают шлюзы и прокси, которые может использовать ваш интернет-провайдер.
Cache-Control: max-age=3600, public
"public" означает, что ответ может быть кэширован кем угодно. "max-age" указывает, сколько секунд действителен кеш. Разрешение кэширования вашего сайта может снизить нагрузку на сервер и пропускную способность, а также увеличить время загрузки в браузере.
Кэширование также может быть предотвращено с помощью директивы "no-cache".
Cache-Control: no-cache
Content-Type
Этот header указывает "mime-type" документа. Затем браузер определяет, как интерпретировать содержимое на основании этого. Например, страница html (или PHP-скрипт с выходом html) может возвращать это:
Content-Type: text/html; charset=UTF-8
"text" - это тип, а "html" - подтип документа. Заголовок также может содержать больше информации, такой как charset.
Для gif-изображения это может быть отправлено.
Content-Type: image/gif
Браузер может использовать внешнее приложение или расширение браузера на основе mime-type. Например, это приведет к загрузке Adobe Reader:
Content-Type: application/pdf
При загрузке напрямую Apache обычно может обнаружить mime-тип документа и отправить соответствующий header. Кроме того, большинство браузеров имеют некоторую степень отказоустойчивости и автоопределение типов mime, если заголовки указаны неверно или отсутствуют.
Вы можете найти список общих типов mime .
В PHP вы можете использовать функцию finfo_file() для определения mime-типа файла.
Content-Disposition
Этот header указывает браузеру открыть окно загрузки файла, вместо того, чтобы пытаться проанализировать содержимое. Пример:
Content-Disposition: attachment; filename="download.zip"
Это заставит браузер сделать это:
![](https://i1.wp.com/cdn.tutsplus.com/net/uploads/legacy/511_http/download.png)
Обратите внимание, что соответствующий заголовок Content-Type также должен быть отправлен вместе с этим:
Content-Type: application/zip
Content-Disposition: attachment; filename="download.zip"
Content-Length
Когда контент будет передаваться браузеру, сервер может указать его размер (в байтах), используя этот header.
Content-Length: 89123
Это особенно полезно при загрузке файлов. Именно так браузер может определить ход загрузки.
Например, вот сценарий-макет, который я написал, имитирует медленную загрузку.
// it"s a zip file
header("Content-Type: application/zip");
// 1 million bytes (about 1megabyte)
header("Content-Length: 1000000");
// load a download dialogue, and save it as download.zip
header("Content-Disposition: attachment; filename="download.zip"");
// 1000 times 1000 bytes of data
for ($i = 0; $i < 1000; $i++) {
echo str_repeat(".",1000);
// sleep to slow down the download
usleep(50000);
}
Вот результат:
![](https://i2.wp.com/cdn.tutsplus.com/net/uploads/legacy/511_http/download_with_progress.png)
Теперь я собираюсь закомментировать заголовок Content-Length
// it"s a zip file
header("Content-Type: application/zip");
// the browser won"t know the size
// header("Content-Length: 1000000");
// load a download dialogue, and save it as download.zip
header("Content-Disposition: attachment; filename="download.zip"");
// 1000 times 1000 bytes of data
for ($i = 0; $i < 1000; $i++) {
echo str_repeat(".",1000);
// sleep to slow down the download
usleep(50000);
}
Теперь результат такой:
![](https://i1.wp.com/cdn.tutsplus.com/net/uploads/legacy/511_http/download_without_progress.png)
Браузер может только сказать, сколько байтов было загружено, но он не знает общую сумму. И индикатор выполнения не показывает прогресс.
Etag
Это еще один header, который используется для кеширования. Это выглядит так:
Etag: "pub1259380237;gz"
Веб-сервер может отправлять этот header с каждым документом, который он обслуживает. Значение может быть основано на последней изменённой дате, размере файла или даже контрольной сумме файла. Браузер затем сохраняет это значение, так как он кэширует документ. В следующий раз, когда браузер запрашивает тот же файл, он отправляет это в HTTP-запросе:
If-None-Match: "pub1259380237;gz"
Если значение Etag документа совпадает с этим, сервер будет отправлять код 304 вместо 200, и никакого содержимого. Браузер будет загружать содержимое из своего кеша.
Last-Modified
Как следует из названия, этот header указывает дату последнего изменения документа в формате GMT:
Last-Modified: Sat, 28 Nov 2009 03:50:37 GMT
$modify_time = filemtime($file);
header("Last-Modified: " . gmdate("D, d M Y H:i:s", $modify_time) . " GMT");
Это предлагает браузеру другой способ для cache документа. Браузер может отправить это в HTTP-запросе:
Мы уже говорили об этом ранее в разделе "If-Modified-Since".
Location
Этот заголовок используется для перенаправления. Если код ответа 301 или 302, сервер также должен отправить этот header. Например, когда вы перейдете на страницу http://www.nettuts.com , ваш браузер получит следующее:
HTTP/1.x 301 Moved Permanently
...
Location: http://net.tutsplus.com/
...
В PHP вы можете перенаправить surfer так:
Header("Location: http://net.tutsplus.com/");
По умолчанию, это отправит 302 код ответа. Если вы хотите вместо 301 отправить:
Header("Location: http://net.tutsplus.com/", true, 301);
Set-Cookie
Когда веб-сайт хочет установить или обновить файл cookie в вашем браузере, он будет использовать этот header.
Set-Cookie: skin=noskin; path=/; domain=.amazon.com; expires=Sun, 29-Nov-2009 21:42:28 GMT
Set-Cookie: session-id=120-7333518-8165026; path=/; domain=.amazon.com; expires=Sat Feb 27 08:00:00 2010 GMT
Каждый файл cookie отправляется как отдельный header. Обратите внимание, что файлы cookie, установленные с помощью JavaScript, не проходят через HTTP headers.
В PHP вы можете установить cookie-файлы, используя функцию setcookie() , а PHP отправляет соответствующие HTTP headers.
Setcookie("TestCookie", "foobar");
Что приводит к отправке этого заголовка:
Set-Cookie: TestCookie=foobar
Если дата истечения срока действия не указана, cookie удаляется, когда окно браузера закрыто.
WWW-Authenticate
Сайт может отправить этот header для аутентификации пользователя через HTTP. Когда браузер увидит этот header, он откроет диалоговое окно входа в систему.
WWW-Authenticate: Basic realm="Restricted Area"
Что будет выглядеть так:
![](https://i2.wp.com/cdn.tutsplus.com/net/uploads/legacy/511_http/401_prompt.png)
Который мы рассмотрели в предыдущей заметке, существует еще один метод отправки запроса по протоколу HTTP – метод POST. Метод POST тоже очень часто используется на практике.
Если, для того, чтобы обратиться к серверу методом GET, нам достаточно было набрать запрос в URL-адрес, то в методе POST все работает по другому принципу.
Для того, чтобы выполнить этот вид запроса, нам необходимо нажать на кнопку с атрибутом type=»submit», которая расположена на веб-странице. Обратите внимание, что эта кнопка расположена в элементе
![](https://i2.wp.com/webgyry.info/wp-content/uploads/2013/02/19-02-2013-5-28-31.png)
Если пользователь введет в текстовое поле какой-либо текст и нажмет на кнопку «Отправить», то на сервер будет отправлена переменная text со значением того содержимого, которое ввел пользователь. Эта переменная будет отправлена методом POST.
Если в форме написать так: