Анатомия HTTP-запроса


Каждый хороший разработчик должен знать, что происходит под капотом после того, как пользователь введет URL сайта в адресной строке браузера и нажмет кнопку "Перейти". На самом деле это самый частый вопрос на собеседовании. В этой статье мы разберем, что происходит во время обработки HTTP-запроса.


Терминология


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


  • веб-сервер — программное обеспечение на сервере, которое позволяет принять и обработать входящий запрос
  • DNS — сокращение от Domain Name System (система доменных имен), которая просто как телефонная книга, связывает адрес сайта с IP-адресом
  • код ответа — число, которое обозначает тип ответа сервера. Общеизвестными являются 200 (все хорошо), 404 (не найдено), 302 (перенаправление), 500 (внутренняя ошибка сервера)

Шаг 1: поиск DNS


На самом деле веб-адреса представляют собой простую строку, которую выглядит как-то так: 216.58.198.174. Если вы перейдете по этому адресу с помощью браузера, то откроется Google. Доменное имя (google.com) это просто псевдоним, который позволяет пользователю легче запомнить адрес.


Итак, когда пользователь вводит доменное имя (например, google.com), браузер делает запрос к DNS и получает IP-адрес, который связан с этим именем.


Думайте о DNS как о телефонной книге. Вместо того, что запоминать номер Вани, вы можете записать его в телефонную книгу. Затем вы можете просто нажать "позвонить Ване" и ваш телефон найдет его номер в базе, и позвонит по этому номеру. В этой аналогии имя "Ваня" — это доменное имя, его номер — это IP-адрес, а телефонная книга — это DNS.


Шаг 2: выполнение запроса


После того, как браузер получил IP-адрес сервера от DNS, он может приступить к созданию запроса. Запрос содержит в себе заголовок и также может содержать тело запроса (например, данные из формы, которую отправил пользователь).


Заголовок содержит в себе следующие параметры:


  • Request method (метод запроса) — чаще всего это либо GET, либо POST. Обычно GET-запрос используется для получения данных (например при отображении веб-страницы), а POST — при отправке формы или данных (например, при авторизации или отправке почты).
  • Request URL (URL-запроса) — это полный URL, который говорит серверу, какую страницу запрашивает пользователь
  • Protocol (протокол) — версия протокола HTTP (обычно 1.2)

В итоге запрос будет выглядеть так:


GET /about.html HTTP/1.1

Дополнительная информация может быть добавлена ниже. Они представлены в виде пар ключ/значение, где ключ — это идентификатор, название, а значение — собственно сам кусочек информации. Пример ниже включают в себя информацию о браузере пользователя (user-agent), куки (cookies), тип содержимого (content type), хост (host), которое в данном случае является названием домена и т.д. Полный HTTP-запрос выглядит как-то так:


GET /culture/anatomy-web-request HTTP/1.1[CRLF]
Host: viacreative.co.uk[CRLF]
Connection: close[CRLF]
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.95 Safari/537.36
Accept-Encoding: gzip[CRLF]
Accept-Charset: ISO-8859-1,UTF-8;q=0.7,*;q=0.7[CRLF]
Cache-Control: no-cache[CRLF]
Accept-Language: de,en;q=0.7,en-us;q=0.3[CRLF]

Шаг 3: ответ сервера


После того, как сервер получил запрос, он генерирует ответ. Так же как и запрос ответ содержит различную информацию, включая:


  • HTTP-код ответа (смотрите раздел "Терминология"). Если запрос прошел успешно, он (код) обычно равен 200 (все хорошо)
  • дата и время генерации ответа
  • HTML-содержимое страницы

Обычный ответ сервера выглядит как-то так:


HTTP/1.x 200 OK
Transfer-Encoding: chunked
Date: Mon, 19 Dec 2016 15:32:21 GMT
Server: nginx/1.11.5
Connection: close
Content-Type: text/html; charset=UTF-8
Content-Encoding: gzip
Vary: Accept-Encoding, Cookie, User-Agent

<!doctype html>
<html lang="en">
<!-- Rest of the HTML -->

Поле Content-Type говорит, браузеру, какой тип содержимого ему следует ожидать. В данном случае это простой HTML. Таким образом, браузер узнает, что ему нужно отрендерить и показать HTML. Тип содержимого может быть также указан как картинка, видео, JSON и т.д. Это поле говорит браузеру, как нужно обработать полученную информацию.


HTML также подключает различные ресурсы, такие как изображения, видео, шрифты или внешние CSS и JavaScript-файлы. Браузер отправляет запросы к серверу для получения этих ресурсов, а затем размещает их на странице. Если вы откроете инструменты разработчика в Google Chrome (Ctrl+Shift+J) и откроете какой-нибудь сайт, то увидите запросы, которые выполнил браузер (вкладка Network).


Анатомия HTTP-запроса


Заключение


Итак, теперь у вас есть общее представление как работают HTTP-запросы. Конечно все становится намного сложнее, когда дело доходит до отправки формы и загрузки файлов, но это уже совсем другая история.


Оригинал: The Anatomy of a Web Request

Поделиться с друзьями
-->

Комментарии (3)


  1. grossws
    27.12.2016 16:41
    +3

    Во-первых, для "оригинал тут" есть выбор публикация/перевод.


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


  1. lair
    27.12.2016 16:48
    +2

    А почему в ответ на вопрос "что происходит" выбран именно этот уровень абстракции? Почему не разбираются детали TCP/IP соединения? Или HTTPS, которого сейчас много? Или почему не разбирается, что происходит в браузере между моментом нажатия на Enter и отправкой собственно HTTP-запроса?


    В конце концов, почему переход на страницу в браузере приравнивается к HTTP-запросу?


  1. Grief
    27.12.2016 16:48
    +2

    Статья очень-очень базовая. На мой взгляд, ее польза несколько сомнительна, но тем не менее, позволю себе оставить пару замечаний.
    Мне кажется, что упоминание того, что заголовок Host с доменным именем используется веб-сервером для возможности одновременной работы нескольких веб-ресурсов на одном IP-адресе заслуживает упоминания даже в такой базовой статье. Хотя бы для того, чтобы новичку было понятно, почему при блокировке одного IP блокируются другие сайты, хостящиеся на том же адресе.
    "Заголовок" — это на самом деле "строка запроса" (request line), чтобы не создавать путаницы с заголовками (headers), это проблема не перевода, а оригинала. "Пары ключ-значение" — это как раз заголовки.
    И еще, мне кажется, что в самых базовых статьях стоит освещать тот факт, что уже 17 лет протокол HTTP/1.1, позволяет не закрывать соединение после каждого запроса-ответа для того чтобы ускорить работу сети, избавившись от затрат на переподключение для каждого ресурса. Для того, чтобы сервер и клиент понимали, когда данные завершились, используется, на мой взгляд один из самых главных заголовков Content-length, значением которого является размер тела сообщения в байтах. Если игнорировать этот заголовок в своих приложениях, даже при указании HTTP/1.1 в строке ответа сервера, соединение будет фактически HTTP/1.0 (Конечно, если не указан Transfer-Encoding, но вот это уже advanced ИМХО) Вообще, последняя спека написана вполне себе человеческим языком и не слишком длинная.