26 января 2016      11625      3

Что такое Http заголовки (Http headers). Общая теория.

Что такое http заголовки (http headers)?

В этой статье мы рассмотрим, для чего заголовки нужны, не вдаваясь в подробности, какой за что отвечает. Описание ролей самых распространённых заголовков будет дано в следующих статьях.

Все статьи из цикла:

HTTP расшифровывается как HyperText Transfer Protocol (протокол передачи гипертекста). Протокол — это набор правил, по которым разные устройства обмениваются данными. Он был создан в 1990-х годах. Сейчас он используется в сети интернет практически повсеместно. Всё, что вы видите в окне браузера, было получено посредством этого протокола. http заголовки — пожалуй главная вещь в общении между устройствами. Они передают основную информацию об устанавливающемся соединении и о передаваемой информации через это соединение.
Взглянем на схему общения двух устройств. Пусть этими устройствами будут ваш компьютер и какой-нибудь сервер в интернете:

http_diagram

Как видно, браузер отослал http-запрос. Он может выглядеть примерно так:

GET /other-19 HTTP/1.1
Host: www.scriptsite.ru
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.0; ru; 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: ru,en-us;q=0.7,en;q=0.3
Accept-Encoding: gzip,deflate
Accept-Charset: windows-1251,utf-8;q=0.7,*;q=0.7
Keep-Alive: 300
Connection: keep-alive

При этом первая строка является строкой запроса, все остальные строки — это и есть http-заголовки, несущие в себе дополнительную информацию о запросе, о клиенте, который эту инфомрацию запрашивает, о многих других вещах.
В ответ на наш запрос сервер может отослать такие заголовки:

1
2
3
4
5
6
7
8
9
10
11
12
HTTP/1.x 200 OK
Date: Sat, 12 Dec 2009 15:41:52 GMT
Server: Apache/2.0.61 (Unix) mod_ssl/2.0.61 OpenSSL/0.9.8k mod_dp20/0.99.2 PHP/5.2.5 mod_python/3.3.1 Python/2.5.1 mod_ruby/1.2.6 Ruby/1.8.6(2007-09-24)
X-Powered-By: PHP/5.2.5
Set-Cookie: PHPSESSID=ft47gokfee6amv3eda3k1p93s3; path=/
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Pragma: no-cache
Keep-Alive: timeout=10, max=1024
Connection: Keep-Alive
Transfer-Encoding: chunked
Content-Type: text/html

Первая строка — строка статуса. Остальные строки — заголовки. В схеме было показано, что подгружается ещё и содержимое страницы. Но это содержимое обычно не принято отображать в плагинах, просматривающих заголовки. Да и содержимое страницы — это только частный случай. По протоколу же не обязательно страница должна передаваться. Вместо неё могут быть переданы и картинка, и звуковой файл, и видео. И у всех них заголовки будут сильно отличаться.

 




 

Как увидеть http-заголовки?

Для того, чтобы увидеть http-заголовки, я рекомендую следующие плагины для браузера firefox:

  1. Firebug
    В нём просмотр находится во вкладке сеть (net) — все (all). Кроме того, плагин имеет очень много дополнительных функций, полезных веб-разработчику.
  2. Live HTTP Headers
    Плагин предназначен только для просмотра заголовков, разобраться в нём довольно легко. Из приятных особенностей могу отметить то, что в нём можно сгенерировать вручную http-запрос, передав в него параметры вручную.

Если вы пользуетесь браузером Chrome, просмотреть всю информацию можно, нажав на кнопку настройки — инструменты — инструменты разработчика. Вкладка networks.
Пользователям браузера opera ничего посоветовать не могу, так как не дружу с этим браузером. Установив плагины и запустив их, попробуйте обновить страницу. Вы сразу же увидите огромные списки запросов и ответов, посредством которых ваш браузер общался с сервером.

Http-заголовки и доступ к ним в php

Если вы являетесь php-разработчиком, вы можете получить доступ к заголовкам запроса с помощью функции getallheaders(). Для понимания её работы выполним такой код:

1
<?php var_dump(getallheaders());?>

И мы получаем распечатку массива заголовков.

1
2
3
4
5
6
7
8
9
array
  'Host' => string 'www.scriptsite.ru' (length=17)
  'User-Agent' => string 'Mozilla/5.0 (Windows NT 6.1; rv:14.0) Gecko/20100101 Firefox/14.0.1' (length=67)
  'Accept' => string 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8' (length=63)
  'Accept-Language' => string 'ru-ru,ru;q=0.8,en-us;q=0.5,en;q=0.3' (length=35)
  'Accept-Encoding' => string 'gzip, deflate' (length=13)
  'Connection' => string 'keep-alive' (length=10)
  'Referer' => string 'http://localhost/' (length=17)
  'Cache-Control' => string 'max-age=0' (length=9)

Так, например, если мы хотим вывести на экран содержимое заголовка User-Agent, содержащего название и версию браузера, а также название операционной системы пользователя, мы можем воспользоваться таким способом:

1
2
3
4
<?php
    $headers = getallheaders();
    echo $headers['User-Agent'];
?>

Но чаще к ним обращаются через глобальную переменную $_SERVER. Почти для каждого http заголовка есть аналогичное название элемента в этой переменной, образуемого по принципу HTTP_имя_заголовка. Так для того же ‘User_Agent’ есть переменная $_SERVER[‘HTTP_USER_AGENT’];

 




 

Для получения заголовков, которые сервер собирается отправить пользователю, используется функция headers_list(). Как правило, сервер составляет недостающие обязательные заголовки уже в конце работы всех скриптов. Поэтому этот массив будет содержать заголовки либо те, которые сервер создал перед началом выполнения скрипта (и они не будут изменены), либо те, которые мы установили вручную. Вручную их можно установить с помощью функции header(«текст заголовка»);
Выполним такой код:

1
2
3
4
<?php
    header("Фрукт: яблоко");
    var_dump(headers_list());
?>

Увидим распечатку готовых к отправке на момент вызова функции заголовков:

1
2
0 => string 'X-Powered-By: PHP/5.3.8' (length=23)
1 => string 'Фрукт: яблоко' (length=23)

Первый заголовок был установлен автоматически, и он несёт в себе название сервера, на котором выполняется скрипт. Второй — установленный нами вручную. Если бы браузеру нужен был заголовок «Фрукт», он бы взял его из http-ответа сервра и использовал. Но так как наш браузер не нуждается в нём, то он просто игнорирует непонятную ему строку.

Структура http запроса

Наш запрос выглядит следующим образом:

request_header

Первая строка в нём, как уже было сказано раньше, является строкой запроса. Она состоит из трёх частей:

  • method (метод) — указывает, какого рода запрос. Самые распространённые методы: GET, POST, HEAD. О них будет написано в следующем параграфе.
  • path (путь) — как правило, это часть URL, идущая после домена. Например, если вы вводите в адресную строку http://www.scriptsite.ru/about/, значение path будет /about/.
  • protocol (протокол) — используемый протокол. Как правило, состоит из «HTTP» и версии протокола. Обычно, в современных браузерах используется версия 1.1

Дальше идут заголовки в виде строк формата «Имя: значение».
Кстати, данные о cookies также передаются в этом запросе в виде одного из заголовков. Большинство из этих строк не являются обязательными. Запрос может быть сокращён вообще до двух строк:

1
2
GET /article/show/4/ HTTP/1.1 
Host: scriptsite.ru 

Методы запроса

GET

get-запрос обычно используется для запроса документа с передачей некоторых параметров.
Это основной метод, используемый для получения html-страниц, изображений, CSS и JavaScript файлов, и т.д.
Из-за того, что параметры могут быть любыми, а на сервере нет ограничений по способам их обработки, часто метод для запросов данных используют для передачи информации. Например, у нас будет такая форма

1
2
3
4
5
<form method="GET" action="foo.php"
    First Name: <input name="first_name" type="text"> <br
    Last Name: <input name="last_name" type="text"> <br
    <input type="submit" name="action" value="Submit"
</form>

В ней указан метод get, по которому она будет работать. После отправки формы будет создан такой заголовок запроса:

1
GET /foo.php?first_name=John&last_name=Doe&action=Submit HTTP/1.1 

При этом эти параметры будут видны в адресной строке браузера.

POST

Post — метод, используемый для отправки данных на сервер. Несмотря на то, что вы можете отправлять данные серверу методом GET через адресную строку браузера, в большинстве случаев предпочтительнее использовать POST. Отправлять большие объёмы данных через GET непрактично. К тому же GET имеет некоторые ограничения, не позволяющие, например, опубликовать эту статью на моём сайте через одну лишь строку браузера. POST запросы чаще всего используются для передачи web-форм. Давайте изменим форму из предыдущего примера, задав ей метод POST

1
2
3
4
5
<form method="GET" action="foo.php"
    First Name: <input name="first_name" type="text"> <br
    Last Name: <input name="last_name" type="text"> <br
    <input type="submit" name="action" value="Submit"
</form>

Когда мы отправим эту форму, браузер сгенерирует такие заголовки:

1
2
3
4
5
6
7
POST /foo.php HTTP/1.1 
Host: localhost 
...
Content-Type: application/x-www-form-urlencoded 
Content-Length: 43 
first_name=John&last_name=Doe&action=Submit 

В этом заголовке путь состоит только из /foo.php. Ничего больше, никаких параметров.
Заголовки Content-Type и Content-Lenght добавлены автоматически. Они содержат информацию о типе и размере данных.
Все данные передаются после отправки заголовков в таком же виде, как в строке запроса GET

 




 

Метод POST повсеместно используется в AJAX, cURL, и т.д.
Формы загрузки файлов работают только через метод POST

HEAD

Многие из вас могли и не знать об этом типе запросов.
Этот метод работает аналогично post, только сервер не возвращает никакого дополнительного содержимого, кроме заголовков.
Использование этого заголовка бывает оправдано во многих случаях. Например, когда браузер когда-то закешировал файл, а теперь хочет узнать, не изменился ли тот на сервере. Браузер может запросить информацию о нём, не скачивая сам файл полностью.
Кроме того, этот метод часто используется в сервисах, проверяющих ссылки на работоспособность. Он позволяет узнавать, по каким URL адресам ещё есть файлы, а по каким их уже нет, при этом опять же файлы не скачиваются.

Структура http ответа

Сервер отвечает на каждый запрос такими ответами:

response_header

Первая строка — версия протокола.
Далее указывается код статуса сервера. В данном значение кода равно 200. Код статуса показывает браузеру, что именно произошло на сервере во время обработки запроса. 200й статус означает, что наш запрос был успешно обработан, и сервер отправит запрашиваемый документ сразу после передачи заголовков.
В остальных строчках указывается всевозможная информация о передаваемом файле.

К информации о статусах можно ещё добавить факт об ошибке 404. Её название пошло именно из кода 404, который отсылает сервер, когда не может найти файл на своих дисках.
Более подробно о статусах сервера написано в следующей статье.

Все темы на сайте

© 2017 BorPost · Копирование материалов сайта без разрешения запрещено