Кратко про HTTP
Основной протокол, которым мы пользуемся при работе с интернетами, называется HTTP.
Сам протокол не знает о текущем состоянии приложения, т.е. его не волнует содержимое предыдущих запросов и ответов.
Протокол является клиент-серверным, конкретно в данном случае:
Клиент инициирует соединение и посылает запрос серверу
Сервер ждет, пока к нему обратится клиент и пришлет запрос. Получив запрос, обрабатывает его и возвращает ответ с результатом.
Вкратце его можно описать так:
- Посылаем запрос
- Ждем ответа
- Получаем ответ
- Реагируем
Запросы
Например, мы хотим посмотреть страницу http://andv.xyz/index.html из браузера. Отбросив некоторые заголовки, наш запрос будет выглядеть как-то так:
GET /index.html HTTP/1.1
Host: andv.xyz
Accept: text/html
Рассмотрим запрос по частям:
GET
— так называемый метод. В зависимости от метода, сервер может определять, какое действие мы хотим совершить
К примеру, у нас есть страница регистрации с адресом /signup
. В случае, если приходит GET-запрос, мы отдаём пользователю форму, в случае, если приходит POST-запрос, мы обрабатываем введенные данные
/index.html
— строка запроса. По ней мы можем определить, что именно хочет увидеть пользователь. Так же мы можем передавать с её помощью некоторые параметры на сервер, пример мы можем увидеть в том же Google: /search?q=hello
. В приведенном примере, мы передаём параметр q
с текстом hello
HTTP/1.1
— обозначение протокола (HTTP) и его версия (1.1)
Далее идут два заголовка, Host и Accept. Заголовки могут быть совершенно любыми и в зависимости от них, сервер так же может принимать какие-то действия. Например, по заголовку Host
cервер определяет, к какому именно сайту мы обращаемся, что позволяет размещать несколько сайтов на одном ip-адресе (браузер соединяется с определенным ip, который сначала нужно узнать у dns-сервера)
Завершает запрос обязательный перенос строки
Так же для некоторых методов, например POST, мы можем передавать дополнительные данные: тело запроса. Рассмотрим на примере воображаемой страницы регистрации:
POST /login HTTP/1.1
Host: andv.xyz
Accept: text/html
Content-Type: application/x-www-form-urlencodedlogin=hello&password=world
В данном примере мы отправляем два параметра login
и password
со значениями hello
и world
соответственно.
Так же мы можем комбинировать параметры форм и параметры запроса:
POST /login?action=remind HTTP/1.1
Host: andv.xyz
Accept: text/html
Content-Type: application/x-www-form-urlencodedemail=me%40andv.xyz
Здесь мы отправляем query-параметр action
со значением remind
и параметр формы email
со значением me@andv.xyz
. Сейчас стоит обратить внимание на один момент: @
в значении заменилось на %40
. Это называется percent-encoding и подробнее об этом можно узнать здесь
Ответы
Обработав запрос от пользователя, сервер отправляет ему ответ. Посмотрим на пример ответа и его составляющие:
HTTP/1.1 200 OK
Date: Mon, 16 Jan 2017 13:58:16 GMT
Content-Type: text/html; charset=utf-8<!DOCTYPE html>
<html>
<head>
<title>Hello, world!</title
</head>
<body>
<h1>Hello, world!</h1>
</body>
</html>
Что есть что в ответе?
HTTP/1.1
— снова обозначение протокола и его версия, ничего нового
200 OK
— числовой статус ответа и его текстовое обозначение. На основании статуса, браузер узнаёт о статусе запроса. К примеру, 200
означает что всё хорошо, а 404
что страница не найдена. Помимо информационных кодов есть еще и те, на которые браузер как-то реагирует. Например, если браузер увидит 301
статус, это будет означать, что страница перемещена по адресу, указанному в заголовке Location, а 304
говорит о том, что документ не изменился и браузер может использовать закешированную версию. В случае с 300-ми кодами, большинство из них не содержат тело ответа, ограничившись только заголовками
По коду статуса мы можем, к примеру, со стороны javascript проверять успешность запроса. К примеру, если сервер вернул 400
, значит наш запрос содержит неверные параметры и мы можем сообщить об этом пользователю
Далее идут два заголовка. Отличие заголовков запроса от заголовков ответа в том, что в первом случае их обрабатывает сервер, а во втором клиент.
После заголовков этого идет обязательная пустая строка и тело ответа.
В теле ответа содержится то, что должен каким-либо образом обработать браузер. Например, html-текст страницы, либо изображение.
Завершает запрос обязательный перенос строки.
И как оно выглядит на практике?
После того, как браузер получит HTML-код страницы и распарсит его, он по схожей схеме начнет загружать все найденные на ней ресурсы (таблицы стилей, скрипты, картинки и так далее): послали GET-запрос с путём до интересующего ресурса, получили ответ, показали картинку/запустили скрипт/применили css.
Т.е. мы делаем запрос, ждем ответ, получаем и обрабатываем информацию от сервера, делаем следующий запрос.