Руководство по http для начинающих

Протокол передачи гипертекста (HTTP) — это основа жизни в Интернете. Он используется каждый раз при передаче документа или в запросе AJAX. Но HTTP на удивление мало известен некоторым веб-разработчикам.

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

Переизданный урок

Каждые несколько недель мы пересматриваем некоторые из любимых сообщений наших читателей за всю историю сайта. Этот урок впервые был опубликован в ноябре 2010 года.


Почему REST?

REST — простой способ организации взаимодействия между независимыми системами.

REST — простой способ организации взаимодействия между независимыми системами. Он пользуется популярностью с 2005 года и вдохновляет дизайн сервисов, таких как API Twitter. Благодаря тому, что REST обеспечивает взаимодействие с такими разнообразными клиентами, как мобильные телефоны и другие веб-сайты. Теоретически, REST не привязан к сети, но почти всегда реализован как таковой и был вдохновлен HTTP. В результате REST можно использовать везде, где возможен HTTP.

Альтернативой является создание относительно сложных соглашений поверх HTTP. Часто это принимает форму новых XML-языков. Самый яркий пример — SOAP. Вам нужно выучить совершенно новый набор соглашений, но вы никогда не используете HTTP в полную силу. Поскольку REST был вдохновлён HTTP и играет на его сильные стороны, это лучший способ узнать, как работает HTTP.

После первоначального обзора мы рассмотрим каждый из строительных блоков HTTP: URL-адреса, HTTP-команды и коды ответов. Мы также рассмотрим, как использовать их в RESTful. Попутно мы проиллюстрируем теорию примером приложения, которое имитирует процесс отслеживания данных, связанных с клиентами компании через веб-интерфейс.


HTTP

HTTP — это протокол, который позволяет отправлять документы в Интернете.

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

В HTTP есть две разные роли: сервер и клиент. Как правило, клиент всегда инициирует разговор; сервер отвечает. HTTP основан на тексте; то есть сообщения по сути являются битами текста, хотя тело сообщения может также содержать другие носители. Использование текста позволяет легко отслеживать обмен HTTP.

HTTP-сообщения состоят из заголовка и тела. Тело часто может оставаться пустым; оно содержит данные, которые вы хотите передать по сети, чтобы использовать их в соответствии с инструкциями в заголовке. Заголовок содержит метаданные, например информацию о кодировке; но, в случае запроса, он также содержит важные HTTP-методы. В стиле REST вы обнаружите, что данные заголовка часто более значимы, чем тела.


Шпионство HTTP на работе

Если вы используете Chrome Developer Tools или Firefox с расширением Firebug, щелкните на панели Net и установите его в enabled. После этого у вас будет возможность просматривать информацию о HTTP-запросах по мере вашего поиска. Например:

Screenshot of Firebug Net panelScreenshot of Firebug Net panelScreenshot of Firebug Net panel

Другим полезным способом ознакомиться с HTTP является использование выделенного клиента, такого как cURL.

cURL  — это инструмент command line, который доступен во всех основных операционных системах.

После установки cURL введите:

Будет отображен полный диалог HTTP. Запросам предшествует >, а ответам предшествует <.


URLS

URL — это, как вы определяете то, на чём вы хотите работать. Мы говорим, что каждый URL-адрес идентифицирует ресурс. Это те же самые URL-адреса, которые назначены веб-страницам. Фактически, веб-страница — это тип ресурса. Давайте рассмотрим более экзотический пример с нашим образцом приложения, которое управляет списком клиентов компании:

будет идентифицировать всех клиентов, в то время как

определяет клиента с именем ‘Jim’, предполагая, что он единственный с таким именем.

В этих примерах мы обычно не включаем hostname в URL, так как это не имеет никакого отношения к организации интерфейса. Тем не менее, hostname важно для того, чтобы идентификатор ресурса был уникальным во всей сети. Мы часто говорим, что вы отправляете запрос на ресурс к host. Хост включается в заголовок отдельно от пути ресурса, который идёт прямо над заголовком запроса:

1
GET /clients/jim HTTP/1.1
2

3
Host: example.com

Ресурсы лучше всего рассматривать как существительные. Например, следующее не RESTful:

Это связано с тем, что для описания действия используется URL-адрес. Это довольно фундаментальный момент в различиях систем RESTful от систем без RESTful.

Наконец, URL-адреса должны быть максимально точными; всё, что необходимо для уникальной идентификации ресурса, должно быть в URL-адресе. Вам не нужно включать в запрос данные, идентифицирующие ресурс. Таким образом, URL-адреса выступают в качестве полной карты всех данных, обрабатываемых приложением.

Но как вы определяете действие? Например, как сообщить, что вы хотите создать новую запись клиента вместо её получения? Именно здесь вступают в действие глаголы HTTP.


Глаголы HTTP

Каждый запрос указывает определенный HTTP глагол или метод в заголовке запроса. Это первое слово в заголовке запроса. Например,

означает, что используется метод GET, а  

1
DELETE /clients/anne HTTP/1.1

означает использование метода DELETE .

Глаголы HTTP сообщают серверу, что делать с данными, указанными URL.

Глаголы HTTP сообщают серверу, что делать с данными, указанными URL. Запрос может ещё содержать дополнительную информацию в своем теле, которая может потребоваться для выполнения операции — например, данные, которые вы хотите сохранить с ресурсом. Эти данные можно указать в cURL с параметром -d.

Если вы когда-либо создавали HTML-формы, то знакомы с двумя из наиболее важных HTTP-глаголов: GET и POST. Но есть гораздо больше доступных HTTP-глаголов. Наиболее важными для построения RESTful API являются GET, POST, PUT и DELETE. Доступны другие методы, такие как HEAD и OPTIONS, но они более редки (если вы хотите знать обо всех других методах HTTP, официальным источником является IETF).

GET

GET — это самый простой тип HTTP-запроса; которым браузер пользуется каждый раз, когда вы нажимаете ссылку или вводите URL-адрес в адресную строку. Он инструктирует сервер передавать клиенту данные, идентифицированные URL-адресом. Никогда не последует изменений данных на стороне сервера в результате запроса GET. В этом смысле GET-запрос доступен только для чтения, но, конечно, как только клиент получит данные, он может самостоятельно выполнять любые операции с ними, например, форматировать для отображения.

PUT

Запрос PUT используется, когда вы хотите создать или обновить ресурс, указанный URL-адресом. Например,

может создать клиента с именем Robin на сервере. Вы заметите, что REST полностью независим от бэкэнда; в запросе нет ничего, что информирует сервер о том, как данные должны создаваться — просто так должно быть. Это позволяет вам легко менять базовую технологию по необходимости. Запросы PUT содержат данные для использования при обновлении или создании ресурса в body. В cURL вы можете добавить данные в запрос с помощью  -d.

1
curl -v -X PUT -d "some text"

DELETE

DELETE должен выполнять противоположное PUT; его следует использовать, если вы хотите удалить ресурс, указанный URL-адресом запроса.

1
curl -v -X DELETE /clients/anne

Это приведёт к удалению всех данных, связанных с ресурсом, идентифицированных /clients/anne.

POST

POST используется, когда обработка, которую вы хотите выполнить на сервере, должна повторяться, если запрос POST повторяется (то есть, они не являются идемпотентными, подробнее об этом ниже). Кроме того, POST-запросы должны вызывать обработку body запроса как подчинённого URL-адреса, который вы отправляете.

Проще говоря:

не должен вызывать изменение ресурса в /clients/ сам, но ресурс URL начинается с него /clients/. Например, он может добавить в список нового клиента, с id, сгенерированным сервером.

1
/clients/some-unique-id

Запросы PUT легко используются вместо запросов POST и наоборот. Некоторые системы используют только один, некоторые используют POST для создания операций и PUT для операций обновления (поскольку с запросом PUT вы всегда указываете полный URL-адрес), некоторые используют POST для обновлений и PUT для создания.

Часто запросы POST используются для запуска операций на сервере, которые не вписываются в парадигму Create/Update/Delete; но это, однако, выходит за рамки REST. В нашем примере мы будем полностью придерживаться PUT.


Классификация методов HTTP  

Безопасные и небезопасные методы:

безопасными являются методы, которые никогда не изменяют ресурсы. Единственными безопасными методами, из четырёх перечисленных выше, является GET. Другие небезопасны, так как они могут привести к модификации ресурсов.

Idempotent методы:

Эти методы достигают того же результата, независимо от того, сколько раз запрос повторяется: это GET, PUT и DELETE. Единственным неидемпотентным методом является POST. PUT и DELETE, считающиеся идемпотентами, могут быть неожиданными, хотя, на самом деле, это довольно легко объяснить: повторение метода PUT с точно таким же body должно модифицировать ресурс таким образом, чтобы он оставался идентичным описанному в предыдущем запросе PUT: ничего не изменится! Аналогичным образом, нет смысла дважды удалять ресурс. Из этого следует, что независимо от того, сколько раз запрос PUT или DELETE повторяется, результат должен быть таким же, как если бы это было сделано только один раз.

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


Представительства

HTTP-клиент и HTTP-сервер обмениваются информацией о ресурсах, определённых URL-адресами.

Мы можем суммировать то, что мы узнали до сих пор, следующим образом: HTTP-клиент и HTTP-сервер обмениваются информацией о ресурсах, определённых URL-адресами.

Мы говорим, что запрос и ответ содержат представление ресурса. Под представлением мы подразумеваем информацию в определённом формате о состоянии ресурса или о том, каким это состояние должно быть в будущем. Оба, и header, и body — являются частями представления.

Заголовки HTTP, содержащие метаданные, жёстко определяются спецификацией HTTP; они могут содержать только простой текст и должны быть отформатированы определённым образом.

Тело может содержать данные в любом формате, и именно здесь видна сила HTTP. Вы знаете, что можете отправлять простой текст, изображения, HTML и XML на любом человеческом языке. Через метаданные запроса или различные URL-адреса вы можете выбирать между различными представлениями для одного и того же ресурса. Например, вы можете отправить веб-страницу в браузеры и JSON в приложения.

HTTP-ответ должен указывать тип содержимого body. Это делается в заголовке, в поле Content-Type; например:

1
Content/Type: application/json

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


Библиотеки клиента HTTP

cURL — это, чаще всего, HTTP-решение для PHP-разработчиков.

Чтобы поэкспериментировать с различными методами запроса, вам нужен клиент, который позволит указать, какой метод использовать. К сожалению, формы HTML не подходят для счёта, так как они позволяют делать только запросы GET и POST. В реальной жизни API-интерфейсы доступны программно через отдельное клиентское приложение или через JavaScript в браузере.

Именно поэтому в дополнение к серверу важно иметь хорошие возможности HTTP-клиента на выбранном вами языке программирования.

Очень популярная клиентская HTTP-библиотека, опять же, cURL. Вы уже были ознакомлены с командой cURL ранее в этом уроке. CURL включает в себя как автономную программу командной строки, так и библиотеку, которая может использоваться различными языками программирования. В частности, cURL является, чаще всего, идеальным решением HTTP-клиента для разработчиков PHP. Другие языки, такие как Python, предлагают больше собственных клиентских HTTP-библиотек.


Настройка примера приложения

Я хочу показать как можно более низкий уровень функциональности.

Наш пример PHP-приложения чрезвычайно тощ. Я хочу выставить  как можно более низкоуровневую функциональность, без какой-либо магии framework . Я также не хотел использовать настоящий API, например, Twitter, потому что они могут неожиданно меняться, вам нужно настроить аутентификацию, что может быть проблемой и вы не сможете изучить реализацию.

Чтобы запустить пример приложения, вам необходимо установить PHP5 и веб-сервер с механизмом для запуска PHP. Текущая версия должна быть не ниже версии 5.2, чтобы иметь доступ к функциям json_encode () и json_decode ().

Что касается серверов, наиболее распространенным вариантом является Apache с mod_php, но вы можете использовать любые альтернативы, которые вам удобны. Существует пример конфигурации Apache, который содержит правила перезаписи, которые помогут вам быстро настроить приложение. Все запросы к любому URL, начиная с /clients/, должны быть направлены в наш файл server.php.

В Apache вам нужно включить mod_rewrite и поместить прилагаемую конфигурацию mod_rewrite где-нибудь в вашей конфигурации Apache или в ваш файл .htacess. Таким образом, server.php будет отвечать на все запросы, поступающие с сервера. То же самое должно быть достигнуто с Nginx, или с любым другим сервером, который вы решите использовать.


Как работает пример приложения

Есть два ключа по обработке запросов REST. Первый ключ — инициировать различную обработку, в зависимости от метода HTTP, даже когда URL-адреса одинаковы. В PHP в глобальном массиве $ _SERVER есть переменная, которая определяет, какой метод был использован для выполнения запроса:

1
$_SERVER['REQUEST_METHOD']

Эта переменная содержит имя метода в виде строки, например ‘GET‘, ‘PUT‘ и далее.

Другой ключ — узнать, какой URL был запрошен. Для этого мы используем другую стандартную переменную PHP:

1
$_SERVER['REQUEST_URI']

Эта переменная содержит URL-адрес, начинающийся с первой косой черты. Например, если имя хоста — ‘example.com‘, ‘http://example.com/‘ вернётся ‘/‘, как ‘http://example.com/test/‘ вернётся ‘/test/‘.

Давайте сначала попытаемся определить, какой URL-адрес был вызван. Мы рассматриваем только URL-адреса, начинающиеся с  ‘clients‘. Все остальные недействительны.

1
$resource = array_shift($paths);
2

3
if ($resource == 'clients') {
4
    $name = array_shift($paths);
5

6
    if (empty($name)) {
7
        $this->handle_base($method);
8
    } else {
9
        $this->handle_name($method, $name);
10
    }
11

12
} else {
13
    // We only handle resources under 'clients'

14
    header('HTTP/1.1 404 Not Found');
15
}

У нас есть два возможных результата:

  • Ресурс — это клиенты, и в этом случае мы возвращаем полный список
  • Существует еще один идентификатор

Если есть ещё один идентификатор, мы предполагаем, что это имя клиента, и, опять же, перенаправляем его в другую функцию, в зависимости от method. Мы используем оператор switch, которого следует избегать в реальном приложении:

1
switch($method) {
2
  case 'PUT':
3
      $this->create_contact($name);
4
      break;
5

6
  case 'DELETE':
7
      $this->delete_contact($name);
8
      break;
9

10
  case 'GET':
11
      $this->display_contact($name);
12
      break;
13

14
  default:
15
      header('HTTP/1.1 405 Method Not Allowed');
16
      header('Allow: GET, PUT, DELETE');
17
      break;
18
  }

Коды ответов

Коды ответа HTTP стандартизируют способ информирования клиента о результате его запроса.

Вы могли заметить, что пример приложения использует PHP header(), передавая некоторые странные строки в качестве аргументов. Функция header() печатает HTTP headers и гарантирует, что они отформатированы соответствующим образом. Заголовки должны быть первым в ответе, поэтому не стоит выводить что-либо ещё до того, как вы закончите с заголовками. Иногда ваш HTTP-сервер может быть настроен для добавления других заголовков в дополнение к тем, которые вы указали в коде.

Заголовки содержат все виды метаинформации; например, текстовую кодировку, используемую в body сообщения, или MIME-тип содержимого body. В этом случае мы явно указываем коды ответа HTTP. Коды ответа HTTP стандартизируют способ информирования клиента о результате его запроса. По умолчанию PHP возвращает код ответа 200, что означает, что ответ выполнен успешно.

Сервер должен вернуть наиболее подходящий код ответа HTTP; таким образом клиент может попытаться исправить свои ошибки, если они есть. Большинство людей знакомы с распространенным кодом ответа 404 Not Found, однако есть много более доступных, в соответствии множеству ситуаций.

Имейте в виду, что значение кода ответа HTTP не является чрезвычайно точным; это следствие того, что HTTP сам по себе довольно общий. Вы должны попытаться найти код ответа, который наиболее точно соответствует ситуации. Но и не слишком переживайте, если не сможете найти точное соответствие.

Вот несколько HTTP-кодов ответа, которые часто используются с REST:

200 OK

Этот код ответа указывает, что запрос был успешным.

201 Created

Это означает, что запрос был успешным и был создан ресурс. Он используется в случае успеха запроса PUT или POST.

400 Bad Request

Запрос был утерян. Это происходит особенно с запросами POST и PUT, когда данные не проходят валидацию или находятся в неправильном формате.

404 Not Found

Этот ответ указывает, что необходимый ресурс не найден. Обычно это относится ко всем запросам, которые указывают на URL-адрес без соответствующего ресурса.

401 Unauthorized

Эта ошибка означает, что вам необходимо выполнить проверку подлинности перед доступом к ресурсу.

405 Method Not Allowed

Используемый метод HTTP не поддерживается для этого ресурса.

409 Conflict

Это указывает на конфликт. Например, вы используете запрос PUT для создания одного и того же ресурса дважды.

500 Internal Server Error

Когда всё остальное терпит неудачу; как правило, ответ 500 используется, когда обработка завершается неудачно из-за непредвиденных обстоятельств на стороне сервера, что вызывает ошибку сервера.


Выполнение образца приложения

Давайте начнем с простого извлечения информации из приложения. Нам нужны детали клиента, ‘jim‘, поэтому давайте отправим простой запрос GET на URL этого ресурса:

1
curl -v http://localhost:80/clients/jim

Это отобразит полные сообщения headers. Последней строкой ответа будет body сообщения; в этом случае это будет JSON, содержащий адрес Jim (помните, что пропуск имени метода приведет к GET-запросу, а также замените localhost: 80 на имя сервера и порт, который вы используете).

Затем мы можем получить информацию для всех клиентов одновременно:

1
curl -v http://localhost:80/clients/

Чтобы создать нового клиента с именем Paul …

1
curl -v -X PUT http://localhost:80/clients/paul -d '{"address":"Sunset Boulevard" }

и вы получите список всех клиентов, содержащих Paul в качестве подтверждения.

Наконец, чтобы удалить клиента:

1
curl -v -X DELETE http://localhost:80/clients/anne

Вы обнаружите, что возвращённый JSON больше не содержит никаких данных об Anne.

Если вы пытаетесь получить несуществующего клиента, например:

1
curl -v http://localhost:80/clients/jerry

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

curl -v -X PUT http://localhost:80/clients/anne

вместо этого получите ошибку 409.


Заключение

В общем, чем меньше предположений за пределами HTTP вы делаете, тем лучше.

Важно помнить, что HTTP был задуман для взаимодействия между системами, которые ничто не разделяет, кроме понимания протокола. В целом, чем меньше допущений за пределами HTTP вы делаете, тем лучше: это позволяет широкому кругу программ и устройств получать доступ к вашему API.

Я использовал PHP в этом уроке, потому что это, скорее всего, язык, наиболее знакомый читателям Nettuts +. Тем не менее, PHP, хотя и предназначен для Интернета, вероятно, не самый лучший язык для работы при REST-способе, поскольку он обрабатывает запросы PUT совсем иначе, чем GET и POST.

Помимо PHP, вы можете принять во внимание следующее:

  • Различные Ruby frameworks (Rails и Sinatra)
  • В Python есть отличная поддержка REST. Должны работать Plain Django и WebOb, или Werkzeug.
  • node.js отлично поддерживает REST

Среди приложений, которые пытаются придерживаться принципов REST, классическим примером является Atom Publishing Protocol, хотя на самом деле он не используется слишком часто на практике. За современным приложением, основанным на философии использования HTTP в полной мере, обратитесь к Apache CouchDB.

Удачи!

Время на прочтение
9 мин

Количество просмотров 1.4M

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

HTTP — широко распространённый протокол передачи данных, изначально предназначенный для передачи гипертекстовых документов (то есть документов, которые могут содержать ссылки, позволяющие организовать переход к другим документам).

Аббревиатура HTTP расшифровывается как HyperText Transfer Protocol, «протокол передачи гипертекста». В соответствии со спецификацией OSI, HTTP является протоколом прикладного (верхнего, 7-го) уровня. Актуальная на данный момент версия протокола, HTTP 1.1, описана в спецификации RFC 2616.

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

Задача, которая традиционно решается с помощью протокола HTTP — обмен данными между пользовательским приложением, осуществляющим доступ к веб-ресурсам (обычно это веб-браузер) и веб-сервером. На данный момент именно благодаря протоколу HTTP обеспечивается работа Всемирной паутины.

Также HTTP часто используется как протокол передачи информации для других протоколов прикладного уровня, таких как SOAP, XML-RPC и WebDAV. В таком случае говорят, что протокол HTTP используется как «транспорт».

API многих программных продуктов также подразумевает использование HTTP для передачи данных — сами данные при этом могут иметь любой формат, например, XML или JSON.

Как правило, передача данных по протоколу HTTP осуществляется через TCP/IP-соединения. Серверное программное обеспечение при этом обычно использует TCP-порт 80 (и, если порт не указан явно, то обычно клиентское программное обеспечение по умолчанию использует именно 80-й порт для открываемых HTTP-соединений), хотя может использовать и любой другой.

Как отправить HTTP-запрос?

Самый простой способ разобраться с протоколом HTTP — это попробовать обратиться к какому-нибудь веб-ресурсу вручную. Представьте, что вы браузер, и у вас есть пользователь, который очень хочет прочитать статьи Анатолия Ализара.

Предположим, что он ввёл в адресной строке следующее:

http://alizar.habrahabr.ru/

Соответственно вам, как веб-браузеру, теперь необходимо подключиться к веб-серверу по адресу alizar.habrahabr.ru.

Для этого вы можете воспользоваться любой подходящей утилитой командной строки. Например, telnet:

telnet alizar.habrahabr.ru 80

Сразу уточню, что если вы вдруг передумаете, то нажмите Ctrl + «]», и затем ввод — это позволит вам закрыть HTTP-соединение. Помимо telnet можете попробовать nc (или ncat) — по вкусу.

После того, как вы подключитесь к серверу, нужно отправить HTTP-запрос. Это, кстати, очень легко — HTTP-запросы могут состоять всего из двух строчек.

Для того, чтобы сформировать HTTP-запрос, необходимо составить стартовую строку, а также задать по крайней мере один заголовок — это заголовок Host, который является обязательным, и должен присутствовать в каждом запросе. Дело в том, что преобразование доменного имени в IP-адрес осуществляется на стороне клиента, и, соответственно, когда вы открываете TCP-соединение, то удалённый сервер не обладает никакой информацией о том, какой именно адрес использовался для соединения: это мог быть, например, адрес alizar.habrahabr.ru, habrahabr.ru или m.habrahabr.ru — и во всех этих случаях ответ может отличаться. Однако фактически сетевое соединение во всех случаях открывается с узлом 212.24.43.44, и даже если первоначально при открытии соединения был задан не этот IP-адрес, а какое-либо доменное имя, то сервер об этом никак не информируется — и именно поэтому этот адрес необходимо передать в заголовке Host.

Стартовая (начальная) строка запроса для HTTP 1.1 составляется по следующей схеме:

Метод URI HTTP/Версия

Например (такая стартовая строка может указывать на то, что запрашивается главная страница сайта):

GET / HTTP/1.1

Метод (в англоязычной тематической литературе используется слово method, а также иногда слово verb — «глагол») представляет собой последовательность из любых символов, кроме управляющих и разделителей, и определяет операцию, которую нужно осуществить с указанным ресурсом. Спецификация HTTP 1.1 не ограничивает количество разных методов, которые могут быть использованы, однако в целях соответствия общим стандартам и сохранения совместимости с максимально широким спектром программного обеспечения как правило используются лишь некоторые, наиболее стандартные методы, смысл которых однозначно раскрыт в спецификации протокола.

URI (Uniform Resource Identifier, унифицированный идентификатор ресурса) — путь до конкретного ресурса (например, документа), над которым необходимо осуществить операцию (например, в случае использования метода GET подразумевается получение ресурса). Некоторые запросы могут не относиться к какому-либо ресурсу, в этом случае вместо URI в стартовую строку может быть добавлена звёздочка (астериск, символ «*»). Например, это может быть запрос, который относится к самому веб-серверу, а не какому-либо конкретному ресурсу. В этом случае стартовая строка может выглядеть так:

OPTIONS * HTTP/1.1

Версия определяет, в соответствии с какой версией стандарта HTTP составлен запрос. Указывается как два числа, разделённых точкой (например 1.1).

Для того, чтобы обратиться к веб-странице по определённому адресу (в данном случае путь к ресурсу — это «/»), нам следует отправить следующий запрос:

GET / HTTP/1.1
Host: alizar.habrahabr.ru

При этом учитывайте, что для переноса строки следует использовать символ возврата каретки (Carriage Return), за которым следует символ перевода строки (Line Feed). После объявления последнего заголовка последовательность символов для переноса строки добавляется дважды.

Впрочем, в спецификации HTTP рекомендуется программировать HTTP-сервер таким образом, чтобы при обработке запросов в качестве межстрочного разделителя воспринимался символ LF, а предшествующий символ CR, при наличии такового, игнорировался. Соответственно, на практике бо́льшая часть серверов корректно обработает и такой запрос, где заголовки отделены символом LF, и он же дважды добавлен после объявления последнего заголовка.

Если вы хотите отправить запрос в точном соответствии со спецификацией, можете воспользоваться управляющими последовательностями \r и \n:

echo -en "GET / HTTP/1.1\r\nHost: alizar.habrahabr.ru\r\n\r\n" | ncat alizar.habrahabr.ru 80

Как прочитать ответ?

Стартовая строка ответа имеет следующую структуру:

HTTP/Версия Код состояния Пояснение

Версия протокола здесь задаётся так же, как в запросе.

Код состояния (Status Code) — три цифры (первая из которых указывает на класс состояния), которые определяют результат совершения запроса. Например, в случае, если был использован метод GET, и сервер предоставляет ресурс с указанным идентификатором, то такое состояние задаётся с помощью кода 200. Если сервер сообщает о том, что такого ресурса не существует — 404. Если сервер сообщает о том, что не может предоставить доступ к данному ресурсу по причине отсутствия необходимых привилегий у клиента, то используется код 403. Спецификация HTTP 1.1 определяет 40 различных кодов HTTP, а также допускается расширение протокола и использование дополнительных кодов состояний.

Пояснение к коду состояния (Reason Phrase) — текстовое (но не включающее символы CR и LF) пояснение к коду ответа, предназначено для упрощения чтения ответа человеком. Пояснение может не учитываться клиентским программным обеспечением, а также может отличаться от стандартного в некоторых реализациях серверного ПО.

После стартовой строки следуют заголовки, а также тело ответа. Например:

HTTP/1.1 200 OK
Server: nginx/1.2.1
Date: Sat, 08 Mar 2014 22:53:46 GMT
Content-Type: application/octet-stream
Content-Length: 7
Last-Modified: Sat, 08 Mar 2014 22:53:30 GMT
Connection: keep-alive
Accept-Ranges: bytes

Wisdom

Тело ответа следует через два переноса строки после последнего заголовка. Для определения окончания тела ответа используется значение заголовка Content-Length (в данном случае ответ содержит 7 восьмеричных байтов: слово «Wisdom» и символ переноса строки).

Но вот по тому запросу, который мы составили ранее, веб-сервер вернёт ответ не с кодом 200, а с кодом 302. Таким образом он сообщает клиенту о том, что обращаться к данному ресурсу на данный момент нужно по другому адресу.

Смотрите сами:

HTTP/1.1 302 Moved Temporarily
Server: nginx
Date: Sat, 08 Mar 2014 22:29:53 GMT
Content-Type: text/html
Content-Length: 154
Connection: keep-alive
Keep-Alive: timeout=25
Location: http://habrahabr.ru/users/alizar/

<html>
<head><title>302 Found</title></head>
<body bgcolor="white">
<center><h1>302 Found</h1></center>
<hr><center>nginx</center>
</body>
</html>

В заголовке Location передан новый адрес. Теперь URI (идентификатор ресурса) изменился на /users/alizar/, а обращаться нужно на этот раз к серверу по адресу habrahabr.ru (впрочем, в данном случае это тот же самый сервер), и его же указывать в заголовке Host.

То есть:

GET /users/alizar/ HTTP/1.1
Host: habrahabr.ru

В ответ на этот запрос веб-сервер Хабрахабра уже выдаст ответ с кодом 200 и достаточно большой документ в формате HTML.

Если вы уже успели вжиться в роль, то можете теперь прочитать полученный от сервера HTML-код, взять карандаш и блокнот, и нарисовать профайл Ализара — в принципе, именно этим бы на вашем месте браузер сейчас и занялся.

А что с безопасностью?

Сам по себе протокол HTTP не предполагает использование шифрования для передачи информации. Тем не менее, для HTTP есть распространённое расширение, которое реализует упаковку передаваемых данных в криптографический протокол SSL или TLS.

Название этого расширения — HTTPS (HyperText Transfer Protocol Secure). Для HTTPS-соединений обычно используется TCP-порт 443. HTTPS широко используется для защиты информации от перехвата, а также, как правило, обеспечивает защиту от атак вида man-in-the-middle — в том случае, если сертификат проверяется на клиенте, и при этом приватный ключ сертификата не был скомпрометирован, пользователь не подтверждал использование неподписанного сертификата, и на компьютере пользователя не были внедрены сертификаты центра сертификации злоумышленника.

На данный момент HTTPS поддерживается всеми популярными веб-браузерами.

А есть дополнительные возможности?

Протокол HTTP предполагает достаточно большое количество возможностей для расширения. В частности, спецификация HTTP 1.1 предполагает возможность использования заголовка Upgrade для переключения на обмен данными по другому протоколу. Запрос с таким заголовком отправляется клиентом. Если серверу требуется произвести переход на обмен данными по другому протоколу, то он может вернуть клиенту ответ со статусом «426 Upgrade Required», и в этом случае клиент может отправить новый запрос, уже с заголовком Upgrade.

Такая возможность используется, в частности, для организации обмена данными по протоколу WebSocket (протокол, описанный в спецификации RFC 6455, позволяющий обеим сторонам передавать данные в нужный момент, без отправки дополнительных HTTP-запросов): стандартное «рукопожатие» (handshake) сводится к отправке HTTP-запроса с заголовком Upgrade, имеющим значение «websocket», на который сервер возвращает ответ с состоянием «101 Switching Protocols», и далее любая сторона может начать передавать данные уже по протоколу WebSocket.

Что-то ещё, кстати, используют?

На данный момент существуют и другие протоколы, предназначенные для передачи веб-содержимого. В частности, протокол SPDY (произносится как английское слово speedy, не является аббревиатурой) является модификацией протокола HTTP, цель которой — уменьшить задержки при загрузке веб-страниц, а также обеспечить дополнительную безопасность.

Увеличение скорости обеспечивается посредством сжатия, приоритизации и мультиплексирования дополнительных ресурсов, необходимых для веб-страницы, чтобы все данные можно было передать в рамках одного соединения.

Опубликованный в ноябре 2012 года черновик спецификации протокола HTTP 2.0 (следующая версия протокола HTTP после версии 1.1, окончательная спецификация для которой была опубликована в 1999) базируется на спецификации протокола SPDY.

Многие архитектурные решения, используемые в протоколе SPDY, а также в других предложенных реализациях, которые рабочая группа httpbis рассматривала в ходе подготовки черновика спецификации HTTP 2.0, уже ранее были получены в ходе разработки протокола HTTP-NG, однако работы над протоколом HTTP-NG были прекращены в 1998.

На данный момент поддержка протокола SPDY есть в браузерах Firefox, Chromium/Chrome, Opera, Internet Exporer и Amazon Silk.

И что, всё?

В общем-то, да. Можно было бы описать конкретные методы и заголовки, но фактически эти знания нужны скорее в том случае, если вы пишете что-то конкретное (например, веб-сервер или какое-то клиентское программное обеспечение, которое связывается с серверами через HTTP), и для базового понимания принципа работы протокола не требуются. К тому же, всё это вы можете очень легко найти через Google — эта информация есть и в спецификациях, и в Википедии, и много где ещё.

Впрочем, если вы знаете английский и хотите углубиться в изучение не только самого HTTP, но и используемых для передачи пакетов TCP/IP, то рекомендую прочитать вот эту статью.

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

Удачи и плодотворного обучения!

Основная масса приложений и веб-страниц взаимодействует с глобальной сетью. Такие коммуникации на смартфонах, компьютерах, а также планшетах и другом оборудовании реализуются при помощи специальных HTTP-запросов.

Далее предстоит рассмотреть HTTP и соответствующие запросы более подробно. Предложенная в статье информация ориентирована на пользователей, которые уже немного разбираются в особенностях функционирования Сети, а также имели опыт в разработке.

HTTP – это HyperText Transfer Protocol. Если перевести аббревиатуру с английского языка, то ее значение будет звучать как «протокол передачи гипертекста». Соответствующий компонент представлен протоколом прикладного уровня, который используется для предоставления доступа ко всем ресурсам в пределах Всемирной паутины.

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

HTTP описывается при помощи спецификации RFC 2016. Его наиболее распространенная версия – это HTTP/2. Иногда разработчикам и системным администраторам приходится все еще иметь дело с более ранней версией – HTTP/1.1.

Принцип работы

Перед изучением запросов по упомянутому протоколу нужно выяснить, как происходит обмен данными. HTTP использует при работе клиент-серверную модель. В ней участвуют клиент и сервер.

Обмен информацией в Сети осуществляется по следующему принципу:

  1. Клиент формирует запрос на некоторый ресурс и отправляет его на сервер.
  2. Сторона сервера принимает запрос. На этом этапе происходит обработка поданной «команды».
  3. Серверная сторона возвращает клиенту ресурс, который был запрошен изначально.

По умолчанию для коммуникации по HTTP используется порт 80. Вместо него допускается выбор другого порта подключения – вручную. Здесь все зависит непосредственно от конфигурации конкретного веб-сервера.

HTTP-сообщения: о запросах и ответах

Server и Client в клиент-серверной модели обмениваются запросами. Информация в рамках функционирования рассматриваемого протокола осуществляется за счет HTTP-сообщений. Они встречаются в нескольких интерпретациях:

  1. Запрос или HTTP Request. Такое название получили сообщения, которые отправляются клиентом на сервер для вызова (инициации) выполнения определенных действий. Обычно запрос отправляется на server, чтобы получить доступ к тому или иному ресурсу. Его основой является HTTP заголовок.
  2. Ответы или HTTP Responses. Это сообщения, которые сервер будет отправлять в качестве ответа на клиентский запрос.

Сообщение (query) помогает передавать информацию в текстовом виде, которая записана в несколько строчек. Оно может быть направлено браузеру или host.

Структура HTTP-сообщения

Структура HTTP запросов и ответов обычно одинаковая. Она включает в себя такие компоненты как:

  1. Строка состояния – start line. Применяется для того чтобы описать версию используемого протокола и указать иные данные. Пример – запрашиваемый ресурс или код ответа. Стартовая строка занимает ровно одну строчку.
  2. HTTP-заголовки – HTTP Headers. Это несколько строчек текста, заданные в определенном формате. Они или уточняют запрос, или описывают тело сообщения.
  3. Пустая строка. Она указывает на то, что все имеющиеся метаданные для ответа или запроса были отправлены «получателю».
  4. Опциональное тело сообщения. Этот компонент включает в свой состав данные, связанные с запросом, или документ (пример – HTML-страница), передаваемый в ответе.

Далее предстоит рассмотреть перечисленные параметры HTTP запроса более подробно.

Стартовая строка

Стартовая строка включает в себя всего три компонента:

  1. Метод запроса. Он помечается как method или verb. Соответствующее слово указывает на то, что именно необходимо проделать с запрошенным ресурсом. Пример – при помощи метода GET можно запросить некоторую информацию по тому или иному адресу. POST ссылается на то, что информация должна быть помещена на имеющийся сервер.
  2. Цель. Она реализована в виде указателя ресурса URL. Он включает в себя: протокол, доменное имя (или IP-адрес), путь к конкретному ресурсу на сервере. В качестве дополнительных параметров может включать в себя указание порта, несколько свойств HTTP Queries и иные опциональные компоненты.
  3. Версия используемого протокола. Определяет структуру следующих за стартовой строкой данных.

Выше – пример стартовой строки. Соответствующая запись указывает на то, что в виде метода используется GET. Обращаться система будет к ресурсу /index.html, используя для этого протокол версии HTTP/1.1.

О методах

Методы используются для указания конкретных действий. Они характеризуют манипуляции, которые пользователь хочет выполнить на серверной части после получения соответствующим компонентом поданного query. Некоторые такие сообщения позволяют браузеру (который в основном выступает в качестве источника данных от клиента) направлять дополнительные данные в тело запроса. Пример – заполненную пользователем электронную форму или документ.

Методы имеют следующую структуру:

  • заголовки запроса;
  • заголовки общего назначения;
  • заголовки представления.

Методов в рассматриваемом языке гипертекста очень много. Ниже приведены наиболее распространенные из них.

Используемый метод Краткая характеристика
GET Запрашивает определенный ресурс. Дополнительные сведения могут быть переданы через строку запроса (Query String) в составе URL.
POST Команда, отправляющая информацию на сервер. С ее помощью можно работать с различными типами документов: текстом, PDF и так далее. Данный метод часто применяется для отправки информации и загрузки данных на веб-сайт.
Head Позволяет получать только заголовки, которые сервер бы вернут при получении GET-команды по тому же ресурсу. Используется соответствующий запрос для того, чтобы узнать размер запрошенного ресурса перед его непосредственной загрузкой.
PUT Создает (размещает) новые компоненты на сервере.
Delete Отвечает за удаление существующих ресурсов на сервере.
Options Запрашивает данные о сервисе, включая информацию о допустимых для применения на серверной стороне HTTP-методов.
Patch Дает возможность частично изменять ресурс по выбранному адресу.

Изучая HTTP команды, необходимо рассмотреть все их элементы. У стартовой строки также есть URL и информация о версии. Все это необходимо знать каждому разработчику.

Информация о URL

В HTTP query есть в стартовой строке поддерживается URL. Он представлен строкой, в которой указывается запрошенных ресурс и некоторые его параметры. Применение соответствующего компонента связано с иными элементами протокола:

  1. Scheme. Это поле, которое используется для указания используемого протокола. Помечается как двоеточие и два слеша (://).
  2. Host. Позволяет указать местоположение ресурса. В нем может размещаться доменное имя или IP-адрес.
  3. Port. Дает возможность задать номер порта, по которому необходимо обращаться к серверу. Начинается с двоеточия, после которого указывается соответствующие параметры. Если port отсутствует, данные компонент будет выбираться по умолчанию в соответствие с указанным значением Scheme.
  4. Path. Компонент HTTP, указывающий на ресурс, к которому обращается пользователь. Если параметр отсутствует, сервер вернет указатель по умолчанию.
  5. Query String. Компонент HTTP, который начинается со знака вопроса. За ним указывается пара «параметр–значение». Между соответствующими сведения ставится символ равенства. Query String можно передавать несколько параметров одновременно. Для этого используется разделитель – &.

Среди перечисленных «настроек» не все компоненты HTTP будут являться обязательными для получения доступа к сервису. Невозможно сформировать «сообщение» без Scheme и Host.

Версии HTTP

Наиболее стандартизированная версия HTTP протокола появилась в 1997 году – HTTP/1.1. Для современных технологий соответствующая разработка имеет ряд недостатков:

  • заголовки, в отличие от тела HTTP запроса, передавались в несжатом виде;
  • большая часть заголовков в сообщениях пропадала;
  • отсутствовала возможность мультиплексирования.

Все перечисленные недостатки были перекрыты HTTP/2. В них сообщения стали разбиваться на фреймы, встраиваемые в поток информации.

Фреймы данные (тело сообщения) отделяются от фреймов заголовка. Это помогло добиться сжатия. С возникновением потоков возникло и мультиплексирование – теперь удается обойтись одним соединением для одновременного подключения нескольких потоков.

Заголовки

HTTP-заголовок представлен строкой формата «Имя–Заголовок:Значение». В качестве разделителя используется символ двоеточия. Названия заголовков не учитывают регистр, но существует негласное правило – каждое новое слово начинать с заглавной буквы. Структура значения напрямую зависит от конкретного заголовка.

В HTTP запросе может передаваться большое количество заголовков. Все они делятся на несколько категорий:

  1. Общее назначение. Такие заголовки будут применяться ко всему сообщению.
  2. Заголовки запроса. Они помогают уточнять простую информацию о запросе, сообщая дополнительный контекст или накладывая ограничения при помощи логических условий.
  3. Заголовки представления. Они используются для непосредственного описания формата данных в сообщении и используемой кодировки. Добавлять их к requests необязательно. 

Выше перечислены наиболее частые и распространенные заголовки (источник — https://selectel.ru/blog/http-request/).

Тело команды

Тело – это завершающая часть HTTP-команды. Она поддерживается не всеми методами. Пример – отсутствие у Het, Head, Delete, Options. Некоторые виды queries способны отправлять данные на сервер в теле запроса. Наиболее распространенный вариант – это Post.

Ответы HTTP

Первая часть основ работы с HTTP-командами изучена. Теперь необходимо разобраться со структурой и особенностями ответов сервера. HTTP-ответ – это сообщение, которое сервер направляет клиенту в ответ на запрос. У него точно такая же структура, как и в случае с query.

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

Стартовая строка ответа – это строка статуса запроса (status line). Она включает в себя такие компоненты как:

  1. Версия протокола.
  2. Код состояния. Он указывает, насколько успешно была произведена обработка имеющегося запроса.
  3. Пояснение. Так называется короткое текстовое описание к коду состояния. Оно применяется для того, чтобы сделать понимание и восприятие «команды» при просмотре ответа более комфортным.

Выше – пример строки состояния.

Код состояния и статусы

Код состояния используется для того, чтобы сообщать клиентам статус посланной ими «команды». Сервер HTTP способен возвращать коды в одной из пяти доступных форм:

Тип (категория) Краткое описание
1xx Информативные коды. Они никак не отражаются на том, как сервер должен обрабатывать запрос.
2xx Будут возвращаться, если «команда» обработана успешно.
3xx Включает в себя коды, которые будут возвращаться при необходимости перенаправления клиента сервером.
4xx Указывают на то, что со стороны клиента отправляются некорректные запросы. Пример – отсутствие поддерживающего метода или обращение к сервису, к которому отсутствует доступ.
5xx Используются при возникновении ошибок.

Наиболее распространенными кодами ответов выступают следующие варианты:

Тип Характеристика
200 ok Успешная обработка команды. Тело ответа обычно включает в себя запрошенный сервис.
302 Found Перенаправление пользователя на другой URL.
400 Bad Request Отображается, если «команда», сформированная клиентом, написана с ошибками. Пример – отсутствие символов, указывающих на факт завершения строки.
403 Forbidden Отсутствие достаточных прав доступа по указанному uri. Встречается, если сервер обнаружил опасные (вредоносные) данные, которые отправлены с клиентской стороны.
404 Not Found Обращение к несуществующему веб-проекту.
500 Internal Error Указывает на невозможность обработки посланной «команды» по определенным причинам.

Существуют не только основные коды состояния, но и коды состояния, объявляемые крупными сетевыми провайдерами и серверными платформами.

Заголовки ответа

Заголовки ответа или Response Headers – элемент, используемый для уточнения ответа. Он никак не влияет на содержимое отправленного сообщения. Существует в том же формате, что и остальные заголовки. Указывается как «Имя–Значение». В качестве разделителя используется двоеточие.

Вот наиболее распространенные заголовки ответа:

Категория Пример Характеристика
Server Server: nginx Включает в себя информацию о сервере, который обрабатывал «команду».
Set-Cookie Set-Cookie–PHPSESSID-bf42938f Включает в себя куки, необходимые для идентификации клиента. Браузер будет парсить куки и сохранять их в своем хранилище для дальнейших «команд».
www-Authenticate WWW-Authenticate: BASIC realm = «localhost» Уведомление для клиента о типе аутентификации, необходимой для доступа к запрашиваемому ресурсу.

Остальные заголовки ответа можно посмотреть в официальной документации. Она есть не только на английском (eng), но и на русском (ru) языке.

Тело ответа

Последняя часть – это тело ответа. Оно поддерживается почти всеми «командами», но не является обязательным компонентом. Коды 201 Created или 204 No Content не поддерживают этот компонент. Они передают в своих заголовках необходимые данные и content-type.

Теперь понятно, что собой представляет строка запроса и из чего она состоит. Лучше разобраться в соответствующем вопросе помогут специальные дистанционные компьютерные курсы. На них с нуля научат не только разрабатывать программное обеспечение, но и работать с базами данных, а также HTTP-командами. В конце обучения выдается сертификат установленного образца.

P. S. Интересуют компьютерные сети, сетевые технологии, протоколы передачи данных? Обратите внимание на следующие курсы в Otus:

  • «Network engineer«;
  • «Network engineer. Basic«.

HTTP для начинающих. Часть 1. Определения

27 марта 2022 г.

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

В этой статье я расскажу об терминах HTTP, инструментах и ​​структуре HTTP-сообщений. Я использую аналогии и метафоры и объясняю вещи разными способами, пытаясь создать полезные ментальные модели. В [Руководстве по HTTP для начинающих — Часть 2: Ответы] (https://app.hackernoon.com/mobile/URwef1IC4FutwiOmJmPM) я подробно расскажу, как написать код для генерации ответных сообщений HTTP на сервере. После этого в [Руководстве по HTTP для начинающих — Часть 3: Запросы] (https://dev.to/abbeyperini/a-beginners-guide-to-http-part-3-requests-63) я расскажу как генерировать HTTP-запросы в клиенте. Наконец, мы немного повеселимся с нашим приложением и некоторыми бесплатными API, созданными для нас другими людьми в Руководстве по HTTP для начинающих — Часть 4: API.

Введение и оглавление

В этой статье предполагается знакомство с основами JavaScript. Я кратко объясню асинхронный JavaScript и основные концепции веб-разработки и предоставлю дополнительные учебные материалы в конце статьи.

Я не буду объяснять TCP, множество определений слова «протокол», или как работает Интернет. Это общий обзор и руководство по использованию HTTP-сообщений в вашем веб-приложении.

  1. Условия веб-разработки

  1. Термины HTTP, асинхронный JavaScript и инструменты HTTP

  1. Структура запроса

  1. [Методы] (#h-методы)

  1. Заголовки запроса

  1. [Тело запроса] (#h-запрос-тело)

  1. Структура ответа

  1. Коды состояния и сообщения

  1. КОРС

  1. Дополнительные ресурсы

Условия веб-разработки

Во-первых, давайте определим несколько терминов, которые я буду часто использовать. Приложение или прикладная программа — это программное обеспечение, работающее на компьютере. Базовая конфигурация большинства веб-приложений — это клиентское приложение, работающее в браузере, таком как Chrome, Firefox или Safari, и серверное приложение, которое предоставляет услуги и ресурсы для клиента. Таким образом, браузер функционирует как среда выполнения для клиентского или клиентского кода. В JavaScript наиболее распространенной средой выполнения, используемой для серверного или серверного кода, является Node.js. Другими словами, клиент — это часть кода, с которой взаимодействует пользователь — нажимает кнопки или читает информацию на странице в своем браузере. Чтобы получить информацию, которую пользователь хочет прочитать, или получить или обновить информацию после того, как пользователь что-то щелкнет, мой клиент будет общаться с моим сервером, используя HTTP.

Я часто использую «приложение» для обозначения моего клиента, потому что не каждому веб-приложению нужен сервер. Можно иметь веб-приложение только с клиентом, например калькулятор, который может выполнять все свои математические операции, не получая больше информации из другого ресурса. Можно только создать клиент и использовать ресурсы на стороне сервера, созданные другими людьми. Возможно, вы видели термин «бессерверный», который относится к способам создания сервисов и ресурсов, подобных серверу, без самостоятельной сборки сервера. На самом деле бессерверные приложения включают создание клиента, а затем использование таких инструментов, как [AWS] (https://aws.amazon.com/serverless/) или [Netlify] (https://www.netlify.com/products/functions/). ) для написания серверного кода внутри клиента. При необходимости ваш клиент будет использовать этот инструмент для выполнения серверного кода на сервере, созданном и размещенном другими людьми. В целях изучения HTTP в этом руководстве мы сосредоточимся на классической [модели клиент-сервер] (https://en.wikipedia.org/wiki/Client%E2%80%93server_model), которую я описал выше.

Внешний вид: Facebook реагирует на смайлики. Внешний вид: смайлики, показанные сзади в виде маленьких людей, засовывающих свои лица в дыры

Я не буду использовать термины «внешняя часть» и «внутренняя часть», поскольку термины «клиент» и «сервер» более конкретны. Например, серверная часть веб-приложения будет включать не только сервер, но также базу данных и любые другие службы и инструменты, используемые сервером.

API означает интерфейс прикладного программирования. Он позволяет двум приложениям, таким как клиент и сервер, взаимодействовать друг с другом. Если сервер — это весь ресторан, API — официант, меню — список методов, которые предоставляет API, а голодный клиент — клиент. Я расскажу о стандартизированных форматах для API и многом другом в части 4.

Библиотека — это пакет/набор/модуль файлов и функций, которые разработчик может использовать в программе, которую он пишет. Поскольку API — это широкий термин, а API используются не только для модели клиент-сервер, методы, предоставляемые библиотекой для использования разработчиком, также могут называться API.

Термины HTTP, асинхронный JavaScript и инструменты HTTP

Существуют разные версии HTTP. HTTP/2 более оптимизирован и безопасен, чем HTTP/1.1, и его использует около половины веб-сайтов. Есть даже HTTP/3, разработанный Google. Возможно, вы уже видели http:// и https:// в своих URL-адресах и предупреждениях браузера о безопасности. Сообщения HTTP шифруются при отправке по HTTPS и не шифруются при отправке по HTTP.

Есть несколько библиотек, которые вы можете использовать для отправки HTTP-сообщений. Например, curl можно использовать из командной строки. Все они используют HTTP, поэтому необходимая им информация одинакова. Отличие заключается в том, где вы можете их использовать, в синтаксисе для создания HTTP-сообщений, предоставляемых ими параметрах и используемом протоколе (например, HTTP против HTTPS, HTTP/1.1 против HTTP/2). Более надежные библиотеки будут делать дополнительные вещи.

HTTPS GO BRRR - jacked shibe с надписью HTTPS, sad shibe с меткой HTTP

При просмотре HTTP-библиотек JavaScript вы можете встретить термин AJAX или Ajax. Это означает асинхронный JavaScript и XML. Проще говоря, асинхронный код работает не по порядку. Отправка сообщения через Интернет и получение обратно сообщения требует времени. Асинхронный код может по существу приостановить выполнение до тех пор, пока данные не будут получены, а затем возобновить выполнение с того места, где оно было остановлено. XML означает расширяемый язык разметки. Это как HTML, но без предопределенных тегов. Это один из форматов, используемых для структурирования данных, которые вы можете отправить в HTTP-сообщении. Ajax может относиться к использованию HTTP с JavaScript, даже если сообщение не содержит данных или данные не структурированы с помощью XML.

Когда вы пишете JavaScript и запускаете его в браузере, у вас есть доступ ко множеству встроенных инструментов. Трудно представить создание веб-сайта без веб-API, таких как HTML DOM и URL. Долгое время единственным доступным HTTP Web API был XMLHttpRequest или XHR. Поскольку это была библиотека Ajax, она, наконец, позволила веб-страницам извлекать данные из базы данных без необходимости обновления всей страницы.

Более современная версия, поддерживаемая всеми браузерами, кроме IE, — это [Fetch] (https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API). Поддержка Fetch была включена в последнюю версию Node.js в январе 2022 года. Она основана на XHR, предоставляя интерфейсы (ожидаемые форматы) для обеих половин. HTTP-разговора и там, где XHR использует обратные вызовы, Fetch использует обещания.

Обратные вызовы и промисы — довольно большие темы. По сути, функция обратного вызова передается в качестве аргумента асинхронной (асинхронной) функции. После того, как асинхронная функция получает то, что ей нужно, выполняется функция обратного вызова. Обещания, с другой стороны, являются объектами, возвращаемыми асинхронными функциями. У них есть три состояния: ожидание, выполнение и отклонение. Асинхронные функции, которые возвращают промисы, могут быть объединены в цепочку с .then() и .catch(). Таким образом, разработчик может передать возвращенное выполненное обещание функции в .then() или передать возвращенное отклоненное обещание в .catch() и обработать ошибку. Javascript также имеет синтаксис async/await, который использует промисы без необходимости явно создавать объекты промисов или передавать их в цепочку. (Тем не менее, вы можете связать их, если хотите.) Другие функции могут вызывать await asyncFunction() и ждать результата, прежде чем продолжить выполнение. Часто результат вызова функции устанавливается в переменную, которая будет использоваться позже. У меня есть примеры кода в части 3 и дополнительные ресурсы для изучения этих тем на конец этой статьи.

Кермит потягивает чай, подпись: «Раньше я давал обещания, теперь я просто жду свои асинхронные функции»

Наконец, есть такие пакеты, как [Axios] (https://github.com/axios/axios). Axios не только предоставляет интерфейсы и использует промисы, но также позволяет разработчику выполнять как HTTP-запросы на стороне клиента в браузере с использованием XHR, так и HTTP-запросы на стороне сервера в Node.js. Он также предоставляет больше возможностей и форматирует ваши сообщения для вас.

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

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

Если мы говорим, что клиент и сервер разговаривают, две половины разговора — это запрос и ответ. Используя HTTP-запрос, клиент запрашивает что-то с сервера.

Каждый запрос требует некоторой информации для работы:

  • Метод: Метод сообщает серверу, что от него хочет клиент.

  • URL-адрес: URL-адрес сообщает инструменту HTTP, куда отправить запрос.

  • Протокол: устанавливается используемым инструментом HTTP.

  • Заголовки: заголовки предоставляют серверу дополнительную информацию о самом запросе.

URL-адрес в сообщении HTTP-запроса работает так же, как когда вы вводите URL-адрес для перехода на веб-страницу в своем браузере. URL-адрес также можно использовать для отправки дополнительной информации — я объясню больше об URL-адресах и о том, как их использовать, в [части 2] (https://app.hackernoon.com/mobile/URwef1IC4FutwiOmJmPM).

Также есть необязательная часть:

  • Тело: если запрос использует метод, который отправляет данные на сервер, данные включаются в тело сразу после заголовков.

Таким образом, сообщение HTTP-запроса будет выглядеть примерно так:
квадрат с POST https://dev.to/hasCar/HTTP/2 в красном поле, Accept: application/json Content-type: application/ json Content-length: 700 в желтом поле, белый пробел и '{"name":"John", "car":true}' в синем поле внутри него

Первая строка, показанная здесь красным цветом, содержит метод, URL-адрес и протокол. Вторая, желтая часть содержит все заголовки. Есть пустая строка, а затем, если есть тело, оно идет в конце, здесь показано синим цветом.

Методы

Самый простой способ объяснить методы — сопоставить их с аббревиатурой постоянного хранилища, CRUD. CRUD означает создание, чтение, обновление и удаление. Вы можете думать об этом с точки зрения базы данных, использующей SQL:

Создать = ВСТАВИТЬ

Читать = ВЫБРАТЬ

Обновление = ОБНОВЛЕНИЕ

Удалить = УДАЛИТЬ

Вы можете думать об этом с точки зрения пользовательского интерфейса приложения:

Создать = пользователи, создающие новый пост

Читать = пользователи, просматривающие свою ленту новостей

Обновление = пользователи, редактирующие сообщение

Удалить = пользователи удаляют сообщение

Для HTTP-запросов:

Создать = ОТПРАВИТЬ

Читать = ПОЛУЧИТЬ

Обновить = ПОСТАВИТЬ или ИСПРАВИТЬ

Удалить = УДАЛИТЬ

Примечание. Есть [больше методов, которые я не рассмотрел] (https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods), потому что я их еще не использовал.

POST отправляет данные на сервер и приводит к изменению. Это требует тела.

GET запрашивает данные с сервера для отправки обратно через ответ. У него нет тела.

PUT отправляет данные на сервер для создания нового ресурса или замены существующего ресурса. Это требует тела.

PATCH отправляет данные на сервер для обновления части существующего ресурса. Это требует тела.

DELETE запрашивает удаление ресурса. Он может иметь тело, если информация, необходимая для идентификации удаляемого ресурса, не содержится в URL-адресе.

Заголовки запроса

Чарли из «Всегда солнечно» разглагольствует о Пепе Сильвии со стеной, обтянутой красной лентой, и почтой позади него, с подписью «Я объясняю заголовки HTTP»

Существует много заголовков HTTP-запросов. Если сервер — концерт, а HTTP-запрос — посетитель, заголовки похожи на билет и идентификатор посетителя. Заголовок Origin сообщает серверу, откуда пришел запрос. Заголовок Accept сообщает серверу, какой формат сервер должен использовать для своего ответа. Заголовок Content-Type сообщает серверу, какой формат использует тело запроса. Некоторые из них автоматически создаются библиотекой HTTP. Некоторые, например заголовки аутентификации, диктуются сервером. Я расскажу об аутентификации в части 3, когда буду запрашивать данные из API, для которого требуется ключ. Многие заголовки вы найдете как в запросе, так и в ответе. Если спецификация HTTP относится к заголовку как к заголовку запроса, она предоставляет информацию только о контексте запроса. Разработчики будут ссылаться на заголовки, включенные в запрос, как на заголовки запроса в разговоре, даже если они также могут использоваться в качестве заголовка ответа и наоборот.

Тело запроса

Тела сообщений HTTP могут быть упакованы в несколько стандартизированных форматов передачи данных. Форматы называются [типы мультимедиа или типы MIME] (https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types), и их много. XML и JSON — это два, которые вы будете видеть чаще всего. Оба они создают тела с одним ресурсом, что означает, что они являются одним файлом в теле сообщения HTTP.

JSON означает нотацию объектов JavaScript. Он имеет стандартный синтаксис, который создает файлы меньшего размера. Встроенные методы JavaScript легко превращают строку JSON в допустимые объекты JavaScript. JSON может быть закодирован только в UTF-8 и имеет типы. XML не имеет типов, может сохранять исходную структуру данных, поддерживает несколько типов кодирования, более безопасен и может отображаться в браузере без каких-либо изменений. XML требует работы для преобразования в JavaScript, и его труднее читать людям, но легче читать машинам. XML против JSON, как JSON стал наиболее широко используемым форматом передачи данных HTTP и какие другие форматы все еще существуют — это огромная тема. [Синопсис Twobithistory] (https://twobithistory.org/2017/09/21/the-rise-and-rise-of-json.html) запустит вас в кроличью нору. Я буду использовать JSON и расскажу о его синтаксисе и встроенных методах JavaScript в части 2 и части 3.

[ ![Муфаса: Смотри, Симба, все, к чему прикасается свет, — это JSON. Симба: Вау. Но как насчет этого темного места? Муфаса: Это XML. Ты никогда не должен туда ходить, Симба практический dev/image/fetch/s—_3zE6x5v—/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9g3o5r5y2s22ijct9duv.jpg)

Тип MIME и кодировка символов, используемые в теле запроса, объявляются в заголовке запроса Content-Type, поэтому сервер знает, как декодировать и обрабатывать данные в теле запроса. Содержимое XML будет иметь application/xml в заголовке. Содержимое JSON будет иметь application/json.

Лучшим примером тела с несколькими ресурсами являются данные, отправленные из HTML-формы на веб-странице. В заголовке Content-Type будет multipart/form-data. Вместо одного тела есть несколько тел, по одному для каждой части формы, каждое со своим собственным заголовком Content-Type. Таким образом, введенные пользователем данные могут быть отправлены на сервер вместе со свойствами HTML-элемента, который он использовал для их ввода. В результате, если у вас есть <input> с таким свойством, как name="first_name", тело запроса будет включать «name=’first_name'» с именем, которое пользователь ввел в <input> .

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

После того, как клиент отправляет HTTP-запрос, сервер возвращает HTTP-ответ. Каждый ответ отправляет некоторую информацию:

  • Протокол: устанавливается используемым инструментом HTTP.

  • Код состояния: набор цифр, который покажет вам, как прошел процесс от запроса до ответа.

  • Сообщение о состоянии: удобочитаемое описание, которое расскажет вам, как прошел процесс от запроса до ответа.

  • Заголовки: Предоставляет клиенту больше информации о самом ответе.

Также есть необязательная часть:

  • Тело: если ответ содержит данные с сервера, они будут включены сюда. Тела запросов и ответов используют одинаковые форматы.

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

Квадрат с HTTP/2 200 OK в красном поле, Access-Control-Allow-Origin: * Access-Control-Allow-Methods: GET, POST Content-type: application/json в желтом поле, a белый пробел и '{"name":"John", "car":true}' в синем прямоугольнике внутри него

Первая строка, показанная здесь красным цветом, содержит протокол, код состояния и сообщение о состоянии. Далее в желтом разделе находятся заголовки. За заголовками следует одна пустая строка. Наконец, если есть данные для отправки обратно, есть тело, показанное здесь синим цветом.

Коды состояния и сообщения

Вы сталкивались с кодами статуса раньше при использовании Интернета. Все видели «404 Not Found», и вы, возможно, видели «403 Forbidden». Тот, на который вы будете надеяться при написании HTTP-запросов, — это успешный «200 OK». Те, которые вы не хотите видеть при написании кода на стороне клиента, находятся в 400-х, например «400 Bad Request» и «405 Method Not Allowed». Проблемы с сервером будут в пределах 500, например «500 Внутренняя ошибка службы» или «503 Служба недоступна».

Backend передает Frontend заметку в классе. Фронтенд оборачивается, хмурясь. В примечании говорится: «Внутренняя ошибка сервера 500»

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

Если вы предпочитаете узнавать свои коды состояния и сообщения, сопровождаемые изображениями животных, проверьте [HTTP Cats] (https://http.cat/) и [HTTP Status Dogs] (https://httpstatusdogs.com/417- ожидание не оправдалось).

КОРС

Поскольку большинство, но не все [заголовки CORS] (https://developer.mozilla.org/en-US/docs/Glossary/CORS) являются заголовками запросов, давайте углубимся в CORS здесь.

[CORS] (https://www.codecademy.com/article/what-is-cors) означает совместное использование ресурсов между источниками. По умолчанию браузеры и серверы, на которых работает JavaScript, используют CORS для блокировки запросов от клиента, источник которого отличается от сервера, в целях безопасности. Целью CORS является защита клиента и сервера от выполнения вредоносного кода, содержащегося в HTTP-запросе, и предотвращение кражи данных с сервера.

Для большинства браузеров источник относится к хосту, протоколу и порту, если он указан. Хост — это часть URL-адреса после www. и перед /. Таким образом, для www.google.com хостом является google.com. Протокол HTTP против HTTPS и HTTP/1.1 против HTTP/2. Порт будет 3000 в http://localhost:3000.

Прежде чем ваш исходный запрос будет отправлен, HTTP отправит предварительный запрос с некоторыми заголовками, такими как источник и метод, чтобы проверить, является ли запрос, который вы хотите сделать, безопасным. Затем сервер отправляет ответ предварительной проверки с заголовками CORS, такими как Access-Control-Allow-Origin и Access-Control-Allow-Methods, которые сообщают браузеру, разрешен ли исходный запрос. Это когда запрос будет заблокирован CORS, если он будет.

Твит Эбби Перини «CORS пишется заглавными буквами, потому что рано или поздно вы начнете кричать об этом».

Вы можете указать, разрешает ли сервер запросы CORS, только если вы пишете серверный код. Например, ответ сервера будет включать заголовок Access-Control-Allow-Origin, в котором перечислены источники, которые могут получить запрос. Если вашего источника нет в списке в заголовке Access-Control-Allow-Origin в ответе, ваш запрос будет заблокирован, и вы не сможете изменить это, если не напишите код, который отправляет ответы.

Если сервер ослабляет ограничения CORS, он обычно заменяет его обязательной проверкой подлинности или использует заголовок Access-Control-Allow-Methods, чтобы ограничить методы запроса только GET. Аутентификацию можно отправить в заголовках или URL (подробнее об этом в части 3).

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

Дополнительные ресурсы

Если вы только начинаете знакомиться с асинхронным Javascript, я настоятельно рекомендую бросить все и посмотреть два видео прямо сейчас: Филип Робертс, «Что, черт возьми, это цикл событий?» и [«In The Loop» Джейка Арчибальда] (https://youtu.be/cCOL7MC4Pl0).

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

  • https://www.digitalocean.com/community/tutorials/understanding-the-event-loop-callbacks-promises-and-async-await-in-javascript

  • https://www.better.dev/callbacks-promises-and-async

  • https://theunlikelydeveloper.com/javascript-callbacks/

  • https://bitsofco.de/javascript-promises-101/

  • https://javascript.info/async-await

Заключение

Было много определений, прежде чем мы добрались до кода! HTTP-сообщения сложны, но они также являются основой веб-приложений. Если вы остались в замешательстве или вам нужны дополнительные ресурсы по теме, которую я затронул, не стесняйтесь оставлять комментарии ниже.

Затем ознакомьтесь с [Руководство по HTTP для начинающих — Часть 2: Ответы] (https://app.hackernoon.com/mobile/URwef1IC4FutwiOmJmPM) и [Руководство по HTTP для начинающих — Часть 3: Запросы] (https://dev .to/abbeyperini/a-beginners-guide-to-http-part-3-requests-63)!

Вскоре:

  • Руководство для начинающих по HTTP — Часть 4: API

Также опубликовано здесь


Оригинал

HTTP — это протокол передачи гипертекста между распределёнными системами. По сути, http является фундаментальным элементом современного Web-а. Как уважающие себя веб разработчики, мы должны знать о нём как можно больше.

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

Также в этой статье я буду, в основном, ссылаться на стандарт RFC 2616: Hypertext Transfer Protocol — HTTP/1.1.

Основы HTTP

HTTP обеспечивает общение между множеством хостов и клиентов, а также поддерживает целый ряд сетевых настроек.

В основном, для общения используется TCP/IP, но это не единственный возможный вариант. По умолчанию, TCP/IP использует порт 80, но можно заюзать и другие.

Общение между хостом и клиентом происходит в два этапа: запрос и ответ. Клиент формирует HTTP запрос, в ответ на который сервер даёт ответ (сообщение). Чуть позже, мы более подробно рассмотрим эту схему работы.

Текущая версия протокола HTTP — 1.1, в которой были введены некоторые новые фишки. На мой взгляд, самые важные из них это: поддержка постоянно открытого соединения, новый механизм передачи данных chunked transfer encoding, новые заголовки для кэширования. Что-то из этого мы рассмотрим во второй части данной статьи.

URL

Сердцевиной веб-общения является запрос, который отправляется через Единый указатель ресурсов (URL). Я уверен, что вы уже знаете, что такое URL адрес, однако для полноты картины, решил всё-таки сказать пару слов. Структура URL очень проста и состоит из следующих компонентов:

Протокол может быть как http для обычных соединений, так и https для более безопасного обмена данными. Порт по умолчанию — 80. Далее следует путь к ресурсу на сервере и цепочка параметров.

Методы

С помощью URL, мы определяем точное название хоста, с которым хотим общаться, однако какое действие нам нужно совершить, можно сообщить только с помощью HTTP метода. Конечно же существует несколько видов действий, которые мы можем совершить. В HTTP реализованы самые нужные, подходящие под нужды большинства приложений.

Существующие методы:

GET: получить доступ к существующему ресурсу. В URL перечислена вся необходимая информация, чтобы сервер смог найти и вернуть в качестве ответа искомый ресурс.

POST: используется для создания нового ресурса. POST запрос обычно содержит в себе всю нужную информацию для создания нового ресурса.

PUT: обновить текущий ресурс. PUT запрос содержит обновляемые данные.

DELETE: служит для удаления существующего ресурса.

Данные методы самые популярные и чаще всего используются различными инструментами и фрэймворками. В некоторых случаях, PUT и DELETE запросы отправляются посредством отправки POST, в содержании которого указано действие, которое нужно совершить с ресурсом: создать, обновить или удалить.

Также HTTP поддерживает и другие методы:

HEAD: аналогичен GET. Разница в том, что при данном виде запроса не передаётся сообщение. Сервер получает только заголовки. Используется, к примеру, для того чтобы определить, был ли изменён ресурс.

TRACE: во время передачи запрос проходит через множество точек доступа и прокси серверов, каждый из которых вносит свою информацию: IP, DNS. С помощью данного метода, можно увидеть всю промежуточную информацию.

OPTIONS: используется для определения возможностей сервера, его параметров и конфигурации для конкретного ресурса.

Коды состояния

В ответ на запрос от клиента, сервер отправляет ответ, который содержит, в том числе, и код состояния. Данный код несёт в себе особый смысл для того, чтобы клиент мог отчётливей понять, как интерпретировать ответ:

1xx: Информационные сообщения

Набор этих кодов был введён в HTTP/1.1. Сервер может отправить запрос вида: Expect: 100-continue, что означает, что клиент ещё отправляет оставшуюся часть запроса. Клиенты, работающие с HTTP/1.0 игнорируют данные заголовки.

2xx: Сообщения об успехе

Если клиент получил код из серии 2xx, то запрос ушёл успешно. Самый распространённый вариант — это 200 OK. При GET запросе, сервер отправляет ответ в теле сообщения. Также существуют и другие возможные ответы:

  • 202 Accepted: запрос принят, но может не содержать ресурс в ответе. Это полезно для асинхронных запросов на стороне сервера. Сервер определяет, отправить ресурс или нет.
  • 204 No Content: в теле ответа нет сообщения.
  • 205 Reset Content: указание серверу о сбросе представления документа.
  • 206 Partial Content: ответ содержит только часть контента. В дополнительных заголовках определяется общая длина контента и другая инфа.

3xx: Перенаправление

Своеобразное сообщение клиенту о необходимости совершить ещё одно действие. Самый распространённый вариант применения: перенаправить клиент на другой адрес.

  • 301 Moved Permanently: ресурс теперь можно найти по другому URL адресу.
  • 303 See Other: ресурс временно можно найти по другому URL адресу. Заголовок Location содержит временный URL.
  • 304 Not Modified: сервер определяет, что ресурс не был изменён и клиенту нужно задействовать закэшированную версию ответа. Для проверки идентичности информации используется ETag (хэш Сущности — Enttity Tag);

4xx: Клиентские ошибки

Данный класс сообщений используется сервером, если он решил, что запрос был отправлен с ошибкой. Наиболее распространённый код: 404 Not Found. Это означает, что ресурс не найден на сервере. Другие возможные коды:

  • 400 Bad Request: вопрос был сформирован неверно.
  • 401 Unauthorized: для совершения запроса нужна аутентификация. Информация передаётся через заголовок Authorization.
  • 403 Forbidden: сервер не открыл доступ к ресурсу.
  • 405 Method Not Allowed: неверный HTTP метод был задействован для того, чтобы получить доступ к ресурсу.
  • 409 Conflict: сервер не может до конца обработать запрос, т.к. пытается изменить более новую версию ресурса. Это часто происходит при PUT запросах.

5xx: Ошибки сервера

Ряд кодов, которые используются для определения ошибки сервера при обработке запроса. Самый распространённый: 500 Internal Server Error. Другие варианты:

  • 501 Not Implemented: сервер не поддерживает запрашиваемую функциональность.
  • 503 Service Unavailable: это может случиться, если на сервере произошла ошибка или он перегружен. Обычно в этом случае, сервер не отвечает, а время, данное на ответ, истекает.

Форматы сообщений запроса/ответа

На следующем изображении вы можете увидеть схематично оформленный процесс отправки запроса клиентом, обработка и отправка ответа сервером.

Давайте посмотрим на структуру передаваемого сообщения через HTTP:

message = <start-line>
          *(<message-header>)
          CRLF
          [<message-body>]

<start-line> = Request-Line | Status-Line
<message-header> = Field-Name ':' Field-Value

Между заголовком и телом сообщения должна обязательно присутствовать пустая строка. Заголовков может быть несколько:

  • Общие заголовки
  • Заголовки запроса
  • Заголовки ответа
  • Заголовки сущностей

Тело ответа может содержать полную информацию или её часть, если активирована соответствующая возможность (Transfer-Encoding: chunked). HTTP/1.1 также поддерживает заголовок Transfer-Encoding.

Общие заголовки

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

general-header = Cache-Control
               | Connection
               | Date
               | Pragma
               | Trailer
               | Transfer-Encoding
               | Upgrade
               | Via
               | Warning

Что-то мы уже рассмотрели в этой статье, что-то подробней затронем во второй части.

Заголовок via используется в запросе типа TRACE, и обновляется всеми прокси-серверами.

Заголовок Pragma используется для перечисления собственных заголовков. К примеру, Pragma: no-cache — это то же самое, что Cache-Control: no-cache. Подробнее об этом поговорим во второй части.

Заголовок Date используется для хранения даты и времени запроса/ответа.

Заголовок Upgrade используется для изменения протокола.

Transfer-Encoding предназначается для разделения ответа на несколько фрагментов с помощью Transfer-Encoding: chunked. Это нововведение версии HTTP/1.1.

Заголовки сущностей

В заголовках сущностей передаётся мета-информация контента:

entity-header  = Allow
               | Content-Encoding
               | Content-Language
               | Content-Length
               | Content-Location
               | Content-MD5
               | Content-Range
               | Content-Type
               | Expires
               | Last-Modified

Все заголовки с префиксом Content- предоставляют информацию о структуре, кодировке и размере тела сообщения.

Заголовок Expires содержит время и дату истечения сущности. Значение “never expires” означает время + 1 код с текущего момента. Last-Modified содержит время и дату последнего изменения сущности.

С помощью данных заголовков, можно задать нужную для ваших задач информацию.

Формат запроса

Запрос выглядит примерно так:

Request-Line = Method SP URI SP HTTP-Version CRLF
Method = "OPTIONS"
       | "HEAD"
       | "GET"
       | "POST"
       | "PUT"
       | "DELETE"
       | "TRACE"

SP — это разделитель между токенами. Версия HTTP указывается в HTTP-Version. Реальный запрос выглядит так:

GET /articles/http-basics HTTP/1.1
Host: www.articles.com
Connection: keep-alive
Cache-Control: no-cache
Pragma: no-cache
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8

Список возможных заголовков запроса:

request-header = Accept
               | Accept-Charset
               | Accept-Encoding
               | Accept-Language
               | Authorization
               | Expect
               | From
               | Host
               | If-Match
               | If-Modified-Since
               | If-None-Match
               | If-Range
               | If-Unmodified-Since
               | Max-Forwards
               | Proxy-Authorization
               | Range
               | Referer
               | TE
               | User-Agent

В заголовке Accept определяется поддерживаемые mime типы, язык, кодировку символов. Заголовки From, Host, Referer и User-Agent содержат информацию о клиенте. Префиксы If- предназначены для создания условий. Если условие не прошло, то возникнет ошибка 304 Not Modified.

Формат ответа

Формат ответа отличается только статусом и рядом заголовков. Статус выглядит так:

Status-Line = HTTP-Version SP Status-Code SP Reason-Phrase CRLF
  • HTTP версия
  • Код статуса
  • Сообщение статуса, понятное для человека

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

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

response-header = Accept-Ranges
                | Age
                | ETag
                | Location
                | Proxy-Authenticate
                | Retry-After
                | Server
                | Vary
                | WWW-Authenticate
  • Age время в секундах, когда сообщение было создано на сервере.
  • ETag MD5 сущности для проверки изменений и модификаций ответа.
  • Location используется для перенаправления и содержит новый URL адрес.
  • Server определяет сервер, где было сформирован ответ.

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

Инструменты для определения HTTP трафика

Существует множество инструментов для мониторинга HTTP трафика. Вот несколько из них:

Наиболее часто используемый — это Chrome Developers Tools:

Если говорить об отладчике, можно воспользоваться Fiddler:

Для отслеживания HTTP трафика вам потребуется curl, tcpdump и tshark.

Библиотеки для работы с HTTP — jQuery AJAX

Поскольку jQuery очень популярен, в нём также есть инструментарий для обработки HTTP ответов при AJAX запросах. Информацию о jQuery.ajax(settings) можете найти на официальном сайте.

Передав объект настроек (settings), а также воспользовавшись функцией обратного вызова beforeSend, мы можем задать заголовки запроса, с помощью метода setRequestHeader().

$.ajax({
    url: 'http://www.articles.com/latest',
    type: 'GET',
    beforeSend: function (jqXHR) {
      jqXHR.setRequestHeader('Accepts-Language', 'en-US,en');
    }
  });

Прочитать объект jqXHR можно с помощью метода jqXHR.getResponseHeader().

Если хотите обработать статус запроса, то это можно сделать так:

$.ajax({
  statusCode: {
    404: function() {
      alert("page not found");
    }
  }
});

Итог

Вот такой вот он, тур по основам протокола HTTP. Во второй части будет ещё больше интересных фактов и примеров.

Понравилась статья? Поделить с друзьями:
  • Ручное окрашивание тканей краской ideal инструкция
  • Руководство свердловской киностудии
  • Диоридин велл инструкция по применению таблетки
  • Амосин суспензия для детей инструкция по применению
  • Sinumerik 808d руководство по параметрам