HTTP — это протокол передачи данных, им пользуются браузеры для получения данных.
Он как правило работает на 80 порту TCP, но нет никаких препятствий для использования на дригих портах. В этом случае в браузере придётся указывать его явным образом.
Протокол версии 1 состоит из пролога, заголовков и тела.
При запросе пролог — это строчка вида «МЕТОД /адрес/ HTTP/версия-протокола». Чаще всего используется метод GET, но он не всегда применим, потому что он не предусматривает тела сообщения и к тому же все GET-запросы должны быть идемпотентны. Это страшное слово обозначает, что все запросы должны возвращать одно и то же, и GET-запрос не должен ничего менять на сервере.
Код ответа сообщает то, как запрос окончился. Например, широко известен код 404. Код 200 мнее известен, но встречается значительно чаще — он означает, что запрос успешен.
Заголовки — это несколько строк в формате Имя-Заголовка: значение заголовка
. В них передаются данные о ресурсе. Самое важное — Content-Type
, он сообщает, что представляет из себя ответ. Например, текст или картинку.
Далее идёт тело ответа. Несмотря на то, что все предыдущие поля были текстовыми, тело также может быть и бинарным. Обратите внимание, когда пошло тело ответа, отправить ещё один заголовок уже нельзя. «headers aready sent» — частая ошибка у php-кодеров.
В версии 1.0 запрос заканчивался разрывом соединения. Но если нужно запросить 10 картинок, разрывать-создавать соединения несколько затратно, и в 1.1 решили что можно не разрывать. А конец сообщения определяется полем Content-Length
или использованием chunked
-кодирования. Эта техника уменьшает накладные расходы, но не убирает их полностью, поэтому иногда используются спрайты — несколько картинок склеенных в одну, чтобы потребовался всего один запрос-ответ.
Более того, тело может быть запаковано GZIP или DEFLATE. Эти два алгоритма на самом деле почти одно и то же и отличаются только заголовком. Такой же алгоритм используется в привычных архивах zip. Браузер должен явно в заголовках запроса указать, что он умеет принимать сжатые ответы.
Бывают случаи, когда запрос делать не нужно, например, страница перезагружается, но фактически ничего не поменялось. В этом случае сервер возвращает 304 Not Modified, и пересылки тела не производится, оно берётся из кэша. Тут-то нам и пригождается идемпотентность.
То, относительно чего ответ не поменялся, определяется заголовками If-None-Match
и If-Modified-Since
.
Можно сделать так, чтобы браузер даже не запрашивал «поменялось-не поменялось», для это (и другого управления кэшем) использются заголовки Cache-Control
и Expires
.
При использовании HTTP следует помнить, что наличие прокси между приёмной и отдающей стороной — нормальное явление, и большая часть заголовков влияет на все стороны в этом процессе.
HTTP 2.0 был основан на SPDY. Теперь это бинарный протокол, и кроме того в нём можно не клеить спрайты — ответ мультиплексируется. Некие задатки мультиплексирования были и в HTTP/1.1, «pipelining», но эта штука нестандартная и не сказать, чтобы сильно надёжная на практике.