Unlimited Plugins, WordPress themes, videos & courses! Unlimited asset downloads! From $16.50/m
Advertisement
  1. Code
  2. Web Development
Code

HTTP Кратко: HTTP-сообщения

by
Difficulty:IntermediateLength:LongLanguages:
This post is part of a series called HTTP Succinctly.
HTTP Succinctly: HTTP Resources
HTTP Succinctly: HTTP Connections

Russian (Pусский) translation by Dima (you can also view the original English article)

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


Запросы и ответы

Представьте, что вы идете к незнакомцу в аэропорту и спрашиваете: «Знаете ли вы сколько время?» Для того, чтобы незнакомец ответил на правильное время, нужно сделать несколько вещей. Во-первых незнакомец должен понять ваш вопрос, потому что если он или она не знает английского, он или она не сможет ответить. Во-вторых, незнакомому человеку потребуется доступ к часам или другому устройству для просмотра времени.

Эта аналогия аэропорта похожа на работу HTTP. Вам, клиенту, нужен ресурс от какой-то другой стороны (ресурс - это информация о времени суток). Таким образом, вы делаете запрос другой стороне, используя язык и словарный запас, который, как вы надеетесь, понимает другая сторона. Если другая сторона понимает ваш запрос и имеет доступный ресурс, он может ответить. Если он понимает запрос, но не имеет ресурса, он все равно может ответить и сказать, что он не знает. Если другая сторона не понимает, что вы говорите, вы можете не получить никакого ответа.

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


Необработанный запрос и ответ

Веб-браузер знает, как отправить HTTP-запрос, открыв сетевое подключение к серверной машине и отправив HTTP-сообщение в виде текста. В запросе нет ничего волшебного - это просто команда в текстовом ASCII-тексте и отформатирована в соответствии со спецификацией HTTP. Любое приложение, которое может отправлять данные по сети, может выполнить HTTP-запрос. Вы даже можете сделать запрос вручную с помощью приложения, такого как Telnet, из командной строки. Обычный сеанс Telnet подключается через порт 23, но, как мы узнали в первой главе, стандартным сетевым портом для HTTP является порт 80.

На следующем рисунке показан скриншот сеанса Telnet, который подключается к odetocode.com на порту 80, выполняет HTTP-запрос и получает ответ HTTP.

Figure 2: Making an HTTP request
Создание HTTP-запроса

Сеанс Telnet начинается с ввода:

Обратите внимание, что клиент Telnet по умолчанию не установлен в Windows 7, Windows Server 2008 R2, Windows Vista или Windows Server 2008. Вы можете установить клиент, выполнив процедуру, указанную по адресу http://technet.microsoft.com/en-us/library/cc771275(v=ws.10).aspx.

Эта команда сообщает операционной системе запустить приложение Telnet и сообщает приложению Telnet подключиться к www.odetocode.com на порту 80.

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

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

Эта информация хоста является необходимой частью информации в сообщении запроса HTTP 1.1. Техническая причина для этого - помочь серверам, поддерживающим несколько веб-сайтов, то есть как на www.odetocode.com, так и на www.odetofood.com можно разместить на одном сервере, а информация о хосте в сообщении поможет веб-серверу запрос на правильное веб-приложение.

После ввода двух предыдущих строк мы можем дважды нажать Enter, чтобы отправить сообщение на сервер. Что вы видите далее в окне Telnet является HTTP-ответ от веб-сервера. Мы рассмотрим более подробные сведения позже, но в ответе говорится, что ресурс, который мы хотим (домашняя страница по умолчанию на www.odetocode.com), переместился. Он переместился на сайт odetocode.com. Теперь клиент должен проанализировать это ответное сообщение и отправить запрос на odetocode.com вместо www.odetocode.com, если он хочет получить домашнюю страницу. Любой веб-браузер автоматически перейдет в новое место.

Эти типы «перенаправления» являются общими, и в этом случае причина заключается в том, чтобы убедиться, что все запросы ресурсов из OdeToCode проходят через odetocode.com, а не www.odetocode.com (это оптимизация поисковой системы, известная как канонизация URL) ,

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


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

Слово GET, введенное в сеанс Telnet, является одним из основных методов HTTP. Каждое сообщение запроса должно включать один из HTTP-методов, и метод сообщает серверу, что запрос хочет сделать. HTTP GET хочет получить, выбрать и извлечь ресурс. Вы могли бы GET изображение (GET /logo.png), или GET файл PDF (GET /documents/report.pdf) или любой другой извлекаемый ресурс, который может хранить сервер. Список общих HTTP-операторов показан в следующей таблице.

Метод Описание
Получить Извлечение ресурса
ПОЛОЖИТЕ Хранить ресурс
УДАЛИТЬ Удалить ресурс
Поместить Обновить ресурс
РУКОВОДИТЕЛЬ Получить заголовки для ресурса

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

Веб-браузер отправляет запрос POST, когда у него есть данные для отправки на сервер. Например, нажав «Добавить в корзину» на сайте, например amazon.com, вы получите сообщение POST в Amazon о том, что мы хотим приобрести. POST запросы обычно генерируются<form>на веб-странице как форма вы заполнить с<input>элементы адреса и данные кредитной карты.


GET и безопасность

Существует часть спецификации HTTP, которая говорит о «безопасных» методах HTTP. Безопасные методы, как следует из названия, не делают ничего «небезопасного», например, уничтожают ресурс, отправляют транзакцию по кредитной карте или отменяют учетную запись. Метод GET является одним из безопасных методов, поскольку он должен только извлекать ресурс, а не изменять состояние ресурса. Отправка запроса GET для изображения JPG не изменяет изображение, оно только выбирает изображение для отображения. Короче говоря, никогда не должно быть побочного эффекта для запроса GET.

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

Figure 3: Refreshing a POST request
Обновление запроса POST

Из-за таких предупреждений многие веб-приложения всегда стараются оставить клиента просмотра результата запроса GET. После того, как пользователь нажимает кнопку на POST-информацию на сервер (например, отправляет заказ), сервер обрабатывает информацию и отвечает перенаправлением HTTP (например, перенаправление, которое мы видели в окне Telnet), сообщающее браузеру GET какой-либо другой ресурс. Браузер выдаст запрос GET, сервер ответит ресурсом «спасибо за заказ», а затем пользователь сможет обновить или распечатать страницу безопасно столько раз, сколько захочет. Это общий шаблон веб-дизайна, известный как шаблон POST/Redirect/GET.

Теперь, когда мы знаем немного больше о POST и GET, давайте поговорим о некоторых распространенных сценариях и посмотрим, когда использовать разные методы.


Общие сценарии GET

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

Когда пользователь нажимает на гиперссылку в браузере, браузер выдает запрос GET на URL, указанный в атрибуте href теги привязки. Вот так будет выглядеть запрос:


Сценарий POST

Теперь представьте, что у вас есть страница, где пользователь должен заполнить информацию для создания учетной записи. Для заполнения информации требуются теги<input>Эти входные данные мы вставляем в<form> и указываем браузеру, куда отправить информацию.

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

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

  1. Ответьте с помощью HTML, указав пользователю, что учетная запись создана. Это приведет к тому, что пользователь просмотрит результат запроса POST, что может привести к проблемам, если он или она обновит страницу - возможно, он попытается подписать их во второй раз!
  2. Ответьте с помощью команды перенаправления, как мы видели ранее, чтобы браузер выдал безопасный запрос GET для страницы, которая сообщает пользователю, что учетная запись была создана.
  3. Ответьте на ошибку с ошибкой или перейдите на страницу с ошибкой. Мы рассмотрим сценарии ошибок чуть позже в книге.

Формы и запросы GET

Третий сценарий является сценарий поиска. В сценарии поиска вам нужен<input>для пользователя, чтобы ввести поисковый запрос. Это может выглядеть следующим образом.

Обратите внимание, что метод в этой форме GET, а не POST. Это потому, что поиск - это операция безопасного извлечения, в отличие от создания учетной записи или бронирования рейса в Бельгию. Браузер будет собирать входные данные в форме и выдавать запрос GET серверу:

Обратите внимание, что вместо ввода входных значений в тело сообщения входные данные входят в часть строки запроса URL-адреса. Браузер отправляет запрос GET для /search?Term = love. Поскольку поисковый запрос находится в URL-адресе, пользователь может пометить URL-адрес или скопировать ссылку и отправить ее по электронной почте. Пользователь также может обновлять страницу столько раз, сколько захочет, потому что операция GET для результатов поиска - это безопасная операция, которая не будет уничтожать или изменять данные.


Слово о методах и ресурсах

Мы довольно много говорили о ресурсах как о физических ресурсах в файловой системе сервера. Довольно часто такие ресурсы, как файлы PDF, видеофайлы, файлы изображений и файлы сценариев, существуют как физические файлы на сервере. Однако URL-адреса, указывающие внутри многих современных веб-приложений, действительно не указывают на файлы. Такие технологии, как ASP.NET и Ruby on Rails, перехватят запрос на ресурс и ответят, как они считают нужным. Они могут читать файл из базы данных и возвращать содержимое в ответе HTTP, чтобы оно выглядело так, как будто этот ресурс действительно существовал на самом сервере.

Хорошим примером является пример POST, который мы использовали ранее, что привело к запросу /account/create. Скорее всего, нет реального файла с именем «create» в каталоге «account». Вместо этого что-то на веб-сервере подбирает этот запрос, считывает и проверяет информацию пользователя и создает запись в базе данных. Ресурс /account/create является виртуальным и не существует. Однако, чем больше вы можете думать о виртуальном ресурсе как о реальном ресурсе, тем лучше ваша архитектура и дизайн приложений будут соответствовать сторонам HTTP.


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

До сих пор мы видели необработанный HTTP-запрос и говорили о двух популярных HTTP-методах - GET и POST. Но, как показал вывод Telnet, сообщение HTTP-запроса больше, чем HTTP-метод. Полное сообщение HTTP-запроса состоит из следующих частей:

Сообщение всегда находится в тексте ASCII, и в строке начала всегда содержатся метод, URL-адрес и версия HTTP (чаще всего это 1.1, который существует с 1999 года). Последний раздел, раздел тела, может содержать данные, такие как параметры входа в учетную запись, которые мы видели ранее. При загрузке файла часть тела может быть довольно большой.

Средний раздел, раздел, где мы видели Host: odetocode.com, содержит один или несколько HTTP-заголовков (помните, что в HTTP 1.1 host является обязательным заголовком). Заголовки содержат полезную информацию, которая может помочь серверу обработать запрос. Например, в последней статье мы говорили о представлениях ресурсов и о том, как клиент и сервер могут вести переговоры о наилучшем представлении ресурса (согласование контента). Например, если клиент хочет увидеть ресурс на французском языке, он может включать заголовок (заголовок Accept-Language), запрашивающий французский контент.

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

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

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

Заголовок Описание
Referer Когда пользователь нажимает на ссылку, клиент может отправить URL-адрес ссылочной страницы в этот заголовок.
Агент пользователя Информация о пользовательском агенте (программном обеспечении), подающем запрос. Многие приложения используют информацию в этом заголовке, если она есть, для определения того, что браузер делает запрос (Internet Explorer 6 против Internet Explorer 9 по сравнению с Chrome и т. д.).
Принять Описывает типы носителей, которые пользовательский агент готов принять. Этот заголовок используется для согласования содержимого.
Принимать язык Описывает языки, которые предпочитает пользовательский агент.
Cookie Содержит информацию о файлах cookie, о которых мы расскажем в следующей главе. Информация о файлах cookie обычно помогает отслеживать сервер или идентифицировать пользователя.
If-Modified-Since  Будет содержать дату, когда агент пользователя в последний раз извлекал (и кэшировал) ресурс. Серверу только нужно отправить обратно весь ресурс, если он был изменен с того времени.

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

Как вы можете видеть, некоторые заголовки содержат несколько значений, например заголовок Accept. Заголовок Accept содержит список типов MIME, которые он любит видеть, включая HTML, XHTML, XML и, наконец, * / * (это означает, что я лучше всего использую HTML, но вы можете отправить мне что-нибудь (* / *), и я попытаюсь выясните это).

Также обратите внимание на появление «q» в некоторых заголовках. Значение q всегда является числом от 0 до 1 и представляет значение качества или «относительную степень предпочтения» для определенного значения. Значение по умолчанию - 1,0, а более высокие номера - более предпочтительны.


Ответ

Ответ HTTP похож на HTTP-запрос. Секции ответа:

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

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


Коды состояния ответа

Код состояния - это число, определенное спецификацией HTTP, и все числа попадают в одну из пяти категорий.

Диапазон Категория
100-199 Информационные
200-299 Успешные
300-399 Перенаправление
400-499 Ошибка клиента
500-599 Ошибка сервера

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

Код Причина Описание
200 Хорошо Код статуса, который все хотят видеть. Код 200 в ответе означает, что все сработало!
301 Перемещен навсегда Ресурс переместился на URL-адрес, указанный в заголовке Location, и клиенту никогда не нужно снова проверять этот URL.

Мы видели пример этого ранее, когда мы использовали Telnet, и сервер перенаправил нас с сайта www.odetocode.com на odetocode.com, чтобы дать поисковым системам канонический URL-адрес.
302 Временно перемещен Ресурс переместился на URL, указанный в заголовке Location. В будущем клиент может запросить URL-адрес, поскольку это временный ход.

Этот тип кода ответа обычно используется после операции POST для перемещения клиента на ресурс, который он может получить с помощью GET (шаблон POST/ Redirect/GET, о котором мы говорили ранее).
304 Не изменено Это сервер, сообщающий клиенту, что ресурс не изменился с момента последнего получения клиентом ресурса, поэтому он может просто использовать локально кэшированную копию.
400 Неправильный запрос Сервер не может понять запрос. Вероятно, запрос использовал неправильный синтаксис.
403 Запрещено Сервер отказал в доступе к ресурсу.
404 Не обнаружено Популярный код, означающий, что ресурс не найден.
500 Внутренняя ошибка сервера На сервере возникла ошибка при обработке запроса. Обычно происходит из-за ошибок программирования в веб-приложении.
503 Сервис недоступен  В настоящий момент сервер не будет обслуживать запрос. Этот код состояния может появляться, когда сервер обрабатывает запросы, поскольку он находится под большой нагрузкой.

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


Коды состояния HTTP в сравнении с вашим приложением

Помните, что код состояния HTTP - это код, указывающий, что происходит на уровне HTTP. Это не обязательно отражает то, что произошло внутри вашей заявки. Например, представьте, что пользователь отправляет на сервер форму входа в систему, но не заполняет поле «Фамилия». Если вашему приложению требуется фамилия, он не сможет создать учетную запись для пользователя. Это не означает, что вам нужно вернуть код ошибки HTTP, указывающий на сбой. Вероятно, вам нужно совсем другое - вы хотите успешно вернуть некоторый контент клиенту с кодом состояния 200 (OK). Содержимое сообщит пользователю, что фамилия не указана. С точки зрения приложения запрос был неудачным, но с точки зрения HTTP запрос был успешно обработан. Это нормально в веб-приложениях.


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

Ответ включает информацию заголовка, которая дает метаданные клиента, которые она может использовать для обработки ответа. Например, тип содержимого будет указываться как тип MIME, о котором мы говорили в последней статье. В следующем ответе мы видим, что тип содержимого - HTML, а набор символов, используемый для кодирования типа, - UTF-8. Заголовки могут также содержать информацию о сервере, например имя программного обеспечения и версию.

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

Существует ряд заголовков, посвященных кешированию и оптимизации производительности. ETag, Expires и Last-Modified предоставляют информацию о кешируемости ответа. ETag - это идентификатор, который изменится при изменении основного ресурса, поэтому сравнение ETags - эффективный способ узнать, нужно ли что-то обновлять. Заголовок Expires сообщает клиенту, как долго кэшировать определенный ресурс. Мы вернемся и посмотрим на кеширование более подробно позже.


Где мы?

В этой главе мы узнали, что HTTP-сообщения всегда попадают парами. Сначала есть запрос, а затем есть ответ. Информация в этих сообщениях доступна в читаемом тексте, и есть множество инструментов, которые вы можете использовать для проверки HTTP-запросов, сделанных на вашем компьютере. Fiddler - один из таких инструментов, если вы используете Windows (http://fiddler2.com). Он прост в использовании, и вы можете видеть необработанные HTTP-запросы, включая все заголовки.

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

Advertisement
Advertisement
Advertisement
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.