Содержание

запросы — структура (заголовок и тело), методы, строка статуса и коды состояния, ответы

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

Базово о протоколе HTTP

HTTP (HyperText Transfer Protocol, дословно — «протокол передачи гипертекста») представляет собой протокол прикладного уровня, используемый для доступа к ресурсам Всемирной Паутины. Под термином гипертекст следует понимать текст, в понятном для человека представлении, при этом содержащий ссылки на другие ресурсы.

Данный протокол описывается спецификацией RFC 2616. На сегодняшний день наиболее распространенной версией протокола является версия HTTP/2, однако нередко все еще можно встретить более раннюю версию HTTP/1.1.

В обмене информацией по HTTP-протоколу принимают участие клиент и сервер. Происходит это по следующей схеме: 

  1. Клиент запрашивает у сервера некоторый ресурс.
  2. Сервер обрабатывает запрос и возвращает клиенту ресурс, который был запрошен.
Схема коммуникации устройств по HTTP-протоколу.

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

Подробнее о протоколе HTTP читайте по ссылке →

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

Данные между клиентом и сервером в рамках работы протокола передаются с помощью HTTP-сообщений. Они бывают двух видов:

  • Запросы (HTTP Requests) — сообщения, которые отправляются клиентом на сервер, чтобы вызвать выполнение некоторых действий. Зачастую для получения доступа к определенному ресурсу. Основой запроса является HTTP-заголовок.
  • Ответы (HTTP Responses) — сообщения, которые сервер отправляет в ответ на клиентский запрос.

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

В целом, как запросы HTTP, так и ответы имеют следующую структуру:

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

Рассмотрим атрибуты HTTP-запроса подробнее.

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

Стартовая строка HTTP-запроса состоит из трех элементов:

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

В примере ниже стартовая строка указывает, что в качестве метода используется GET, обращение будет произведено к ресурсу /index.html, по версии протокола HTTP/1.1:

Основные структурные элементы URL.

Разберемся с каждым из названных элементов подробнее.

Методы

Методы позволяют указать конкретное действие, которое мы хотим, чтобы сервер выполнил, получив наш запрос. Так, некоторые методы позволяют браузеру (который в большинстве случаев является источником запросов от клиента) отправлять дополнительную информацию в теле запроса — например, заполненную форму или документ.

Ниже приведены наиболее используемые методы и их описание:

Разберемся с каждым из названных элементов подробнее.

МетодОписание
GETПозволяет запросить некоторый конкретный ресурс. Дополнительные данные могут быть переданы через строку запроса (Query String) в составе URL (например ?param=value).О составляющих URL мы поговорим чуть позже.
POSTПозволяет отправить данные на сервер. Поддерживает отправку различных типов файлов, среди которых текст, PDF-документы и другие типы данных в двоичном виде. Обычно метод POST используется при отправке информации (например, заполненной формы логина) и загрузке данных на веб-сайт, таких как изображения и документы.
HEADЗдесь придется забежать немного вперед и сказать, что обычно сервер в ответ на запрос возвращает заголовок и тело, в котором содержится запрашиваемый ресурс. Данный метод при использовании его в запросе позволит получить только заголовки, которые сервер бы вернул при получении GET-запроса к тому же ресурсу. Запрос с использованием данного метода обычно производится для того, чтобы узнать размер запрашиваемого ресурса перед его загрузкой.
PUTИспользуется для создания (размещения) новых ресурсов на сервере. Если на сервере данный метод разрешен без надлежащего контроля, то это может привести к серьезным проблемам безопасности.
DELETEПозволяет удалить существующие ресурсы на сервере. Если использование данного метода настроено некорректно, то это может привести к атаке типа «Отказ в обслуживании» (Denial of Service, DoS) из-за удаления критически важных файлов сервера.
OPTIONSПозволяет запросить информацию о сервере, в том числе информацию о допускаемых к использованию на сервере HTTP-методов.
PATCHПозволяет внести частичные изменения в указанный ресурс по указанному расположению.

URL

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

Использование URL неразрывно связано с другими элементами протокола, поэтому далее мы рассмотрим его основные компоненты и строение:

Поле Scheme используется для указания используемого протокола, всегда сопровождается двоеточием и двумя косыми чертами (://).

Host указывает местоположение ресурса, в нем может быть как доменное имя, так и IP-адрес.

Port, как можно догадаться, позволяет указать номер порта, по которому следует обратиться к серверу. Оно начинается с двоеточия (:), за которым следует номер порта. При отсутствии данного элемента номер порта будет выбран по умолчанию в соответствии с указанным значением Scheme (например, для http:// это будет порт 80).

Далее следует поле Path. Оно указывает на ресурс, к которому производится обращение. Если данное поле не указано, то сервер в большинстве случаев вернет указатель по умолчанию (например index.html).

Поле Query String начинается со знака вопроса (?), за которым следует пара «параметр-значение», между которыми расположен символ равно (=). В поле Query String могут быть переданы несколько параметров с помощью символа амперсанд (&) в качестве разделителя.

Не все компоненты необходимы для доступа к ресурсу. Обязательно следует указать только поля Scheme и Host.

Версии HTTP

Раз уж мы упомянули версию протокола как элемента стартовой строки, то стоит сказать об основных отличиях версий HTTP/1. X от HTTP/2.X.

Последняя стабильная, наиболее стандартизированная версия протокола первого поколения (версия HTTP/1.1) вышла в далеком 1997 году. Годы шли, веб-страницы становились сложнее, некоторые из них даже стали приложениями в том виде, в котором мы понимаем их сейчас. Кроме того, объем медиафайлов и скриптов, которые добавляли интерактивность страницам, рос. Это, в свою очередь, создавало перегрузки в работе протокола версии HTTP/1.1.

Стало очевидно, что у HTTP/1.1 есть ряд значительных недостатков:

  • Заголовки, в отличие от тела сообщения, передавались в несжатом виде.
  • Часто большая часть заголовков в сообщениях совпадала, но они продолжали передаваться по сети.
  • Отсутствовала возможность так называемого мультиплексирования — механизма, позволяющего объединить несколько соединений в один поток данных. Приходилось открывать несколько соединений на сервере для обработки входящих запросов.

С выходом HTTP/2 было предложено следующее решение: HTTP/1. X-сообщения разбивались на так называемые фреймы, которые встраивались в поток данных.

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

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

Заголовки

HTTP-заголовок представляет собой строку формата «Имя-Заголовок:Значение», с двоеточием(:) в качестве разделителя. Название заголовка не учитывает регистр, то есть между Host и host, с точки зрения HTTP, нет никакой разницы. Однако в названиях заголовков принято начинать каждое новое слово с заглавной буквы. Структура значения зависит от конкретного заголовка. Несмотря на то, что заголовок вместе со значениями может быть достаточно длинным, занимает он всего одну строчку.

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

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

Ниже можно видеть пример заголовков в запросе:

Самые частые заголовки запроса

ЗаголовокОписание
HostИспользуется для указания того, с какого конкретно хоста запрашивается ресурс. В качестве возможных значений могут использоваться как доменные имена, так и IP-адреса. На одном HTTP-сервере может быть размещено несколько различных веб-сайтов. Для обращения к какому-то конкретному требуется данный заголовок.
User-AgentЗаголовок используется для описания клиента, который запрашивает ресурс. Он содержит достаточно много информации о пользовательском окружении. Например, может указать, какой браузер используется в качестве клиента, его версию, а также операционную систему, на которой этот клиент работает.
ReferИспользуется для указания того, откуда поступил текущий запрос. Например, если вы решите перейти по какой-нибудь ссылке в этой статье, то вероятнее всего к запросу будет добавлен заголовок Refer: https://selectel.ru
AcceptПозволяет указать, какой тип медиафайлов принимает клиент. В данном заголовке могут быть указаны несколько типов, перечисленные через запятую (‘ , ‘). А для указания того, что клиент принимает любые типы, используется следующая последовательность — */*.
CookieДанный заголовок может содержать в себе одну или несколько пар «Куки-Значение» в формате cookie=value. Куки представляют собой небольшие фрагменты данных, которые хранятся как на стороне клиента, так и на сервере, и выступают в качестве идентификатора. Куки передаются вместе с запросом для поддержания доступа клиента к ресурсу. Помимо этого, куки могут использоваться и для других целей, таких как хранение пользовательских предпочтений на сайте и отслеживание клиентской сессии. Несколько кук в одном заголовке могут быть перечислены с помощью символа точка с запятой (‘ ; ‘), который  используется как разделитель.
AuthorizationИспользуется в качестве еще одного метода идентификации клиента на сервере. После успешной идентификации сервер возвращает токен, уникальный для каждого конкретного клиента. В отличие от куки, данный токен хранится исключительно на стороне клиента и отправляется клиентом только по запросу сервера. Существует несколько типов аутентификации, конкретный метод определяется тем веб-сервером или веб-приложением, к которому клиент обращается за ресурсом.

Тело запроса

Завершающая часть HTTP-запроса — это его тело. Не у каждого HTTP-метода предполагается наличие тела. Так, например, методам вроде GET, HEAD, DELETE, OPTIONS обычно не требуется тело. Некоторые виды запросов  могут отправлять данные на сервер в теле запроса: самый распространенный из таких методов — POST.

Ответы HTTP

HTTP-ответ является сообщением, которое сервер отправляет клиенту в ответ на его запрос. Его структура равна структуре HTTP-запроса: стартовая строка, заголовки и тело.

Строка статуса (Status line)

Стартовая строка HTTP-ответа называется строкой статуса (status line). На ней располагаются следующие элементы:

  1. Уже известная нам по стартовой строке запроса версия протокола (HTTP/2 или HTTP/1.1).
  2. Код состояния, который указывает, насколько успешно завершилась обработка запроса.
  3. Пояснение — короткое текстовое описание к коду состояния. Используется исключительно для того, чтобы упростить понимание и восприятие человека при просмотре ответа.

Так выглядит строка состояния ответа.

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

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

КатегорияОписание
1xxКоды из данной категории носят исключительно информативный характер и никак не влияют на обработку запроса.
2xxКоды состояния из этой категории возвращаются в случае успешной обработки клиентского запроса.
3xxЭта категория содержит коды, которые возвращаются, если серверу нужно перенаправить клиента.
4xxКоды данной категории означают, что на стороне клиента был отправлен некорректный запрос. Например, клиент в запросе указал не поддерживаемый метод или обратился к ресурсу, к которому у него нет доступа.
5xxОтвет с кодами из этой категории приходит, если на стороне сервера возникла ошибка.

Полный список кодов состояния доступен в спецификации к протоколу, ниже приведены только самые распространенные коды ответов:

КатегорияОписание
200 OKВозвращается в случае успешной обработки запроса, при этом тело ответа обычно содержит запрошенный ресурс.
302 FoundПеренаправляет клиента на другой URL. Например, данный код может прийти, если клиент успешно прошел процедуру аутентификации и теперь может перейти на страницу своей учетной записи.
400 Bad RequestДанный код можно увидеть, если запрос был сформирован с ошибками. Например, в нем отсутствовали символы завершения строки.
403 ForbiddenОзначает, что клиент не обладает достаточными правами доступа к запрошенному ресурсу. Также данный код можно встретить, если сервер обнаружил вредоносные данные, отправленные клиентом в запросе.
404 Not FoundКаждый из нас, так или иначе, сталкивался с этим кодом ошибки. Данный код можно увидеть, если запросить у сервера ресурс, которого не существует на сервере.
500 Internal ErrorДанный код возвращается сервером, когда он не может по определенным причинам обработать запрос.

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

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

Response Headers, или заголовки ответа, используются для того, чтобы уточнить ответ, и никак не влияют на содержимое тела. Они существуют в том же формате, что и остальные заголовки, а именно  «Имя-Значение» с двоеточием (:) в качестве разделителя.

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

КатегорияПримерОписание
ServerServer: ngnixСодержит информацию о сервере, который обработал запрос. 
Set-CookieSet-Cookie:PHPSSID=bf42938fСодержит куки, требуемые для идентификации клиента. Браузер парсит куки и сохраняет их в своем хранилище для дальнейших запросов.
WWW-AuthenticateWWW-Authenticate: BASIC realm=»localhost»Уведомляет клиента о типе аутентификации, который необходим для доступа к запрашиваемому ресурсу.

Тело ответа

Последней частью ответа является его тело. Несмотря на то, что у большинства ответов тело присутствует, оно не является обязательным. Например, у кодов «201 Created» или «204 No Content» тело отсутствует, так как достаточную информацию для ответа на запрос они передают в заголовке.

Безопасность HTTP-запросов, или что такое HTTPs

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

Да, все верно: данные передаются в открытом виде. HTTP сам по себе не предоставляет никаких средств шифрования.

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

Время рассказать про HTTPs! 

HTTPs (HyperText Transfer Protocol, secure) является расширением HTTP-протокола, который позволяет шифровать отправляемые данные, перед тем как они попадут на транспортный уровень. Данный протокол по умолчанию использует порт 443.

Теперь если мы перехватим не HTTP , а HTTPs-запрос, то не увидим здесь ничего интересного:

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

Повысьте безопасность на сетевых портах с Selectel

Три межсетевых экрана для любых потребностей бизнеса.

Выбрать

Если хотите подробнее узнать о деталях работы протокола, читайте статью в нашем блоге →

Как отправить HTTP-запрос и прочитать его ответ

Теория это, конечно, отлично, но ничего так хорошо не закрепляет материал, как практика

Мы рассмотрим несколько способов, как написать HTTP-запрос в браузер, послать HTTP-запрос на сервер и получить ответ:

  1. Инструменты разработчика в браузере. 
  2. Утилита cURL.

Инструменты разработчика

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

По нажатию комбинации клавиш [Ctrl+Shift+I] или просто [F12] в подавляющем большинстве современных браузеров у нас откроется окно инструментов разработчика, которая представляет собой панель с несколькими вкладками. Нужная нам вкладка обычно называется Network. Перейдем в нее, а в адресной строке введем URL того сайта, на который хотим попасть. В качестве примера воспользуемся сайтом блога Selectel — https://selectel.ru/blog/.

После нажатия Enter сайт начнет загружаться, а открытая вкладка Network — заполняться различными элементами, начиная все больше напоминать приборную панель самолета.

Не спешите пугаться. Это всего лишь список ресурсов, которые нужны для правильного отображения и работы сайта.

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

В данном запросе, например:

  • URL, к которому было совершено обращение — https://selectel. ru/blog,
  • Метод, который был использован в запросе — GET,
  • И в качестве кода возврата сервер вернул нам страницу с кодом статуса — 200 OK 

Утилита cURL

Следующий инструмент, с помощью которого мы сможем послать запрос на тот или иной сервер, это утилита cURL.

cURL (client URL) является небольшой утилитой командной строки, которая позволяет работать с HTTP и рядом других протоколов.

Для отправки запроса и получения ответа мы можем воспользоваться флагом -v и указанием URL того ресурса, который мы хотим получить. «Схему» HTTP-запроса можно увидеть на скрине ниже:

После запуска утилита выполняет: 

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

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

Заключение

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

Тело HTTP-запроса | Протокол HTTP

Зарегистрируйтесь для доступа к 15+ бесплатным курсам по программированию с тренажером

HTTP request и response могут содержать так называемое тело (body).

Мы уже знаем, что сам HTTP запрос состоит из заголовков и опционального тела запроса. Для отделения заголовков от тела существуют определенные правила. Давайте посмотрим на примере, как работать с body и каким образом посылать какие-то данные кроме заголовков. Сделаем HTTP запрос к хосту hexlet.io:

telnet hexlet.io 80
GET / HTTP/1.1
Host: hexlet.io
HTTP/1.1 301 Moved Permanently
Cache-Control: private
Content-Type: text/html; charset=UTF-8
Referrer-Policy: no-referrer
Location: https://34.102.241.4/
Content-Length: 218
Date: Tue, 07 Jul 2020 03:50:16 GMT
<HTML><HEAD><meta http-equiv="content-type" content="text/html;charset=utf-8">
<TITLE>301 Moved</TITLE></HEAD><BODY>
<h2>301 Moved</h2>
The document has moved
<A HREF="https://34.102.241.4/">here</A>.
</BODY></HTML>

В ответ мы получаем какие-то заголовки и далее идет тело, которое нас как раз и интересует. В данном случае это не какая-то страница нашего сайта, а просто страница, которую отдает сервер. Она связана с перенаправлением.

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

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

Во время отправки ответа сервер формирует специальный заголовок, который называется Content-Length. Это и есть ключ к тому как работать с body. Перед тем как отправить тело ответа, происходит вычисление его длины и записывается количество байт.

# число — количество байт
Content-Length: 218

После того, как передан такой заголовок, другая сторона будет ожидать ровно столько байт, сколько в нем указано.

Как мы помним, для response и request это работает абсолютно одинаково. После того как был передан последний символ, соединение закрывается. Стоит уточнить, что закрывается именно HTTP-сессия. На сервере может быть активен keep-alive, но ключевой момент в том, что запрос считается завершенным и отображается.

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

Практика показывает, что не все серверы правильно работают при наличии только заголовка Content-Length. Им не хватает еще одного. Тип содержимого запроса или ответа, которое содержит

body, должен быть как-то идентифицирован. По умолчанию в стандарте сказано, что сервер может сам попытаться определить содержимое контента на основе различных способов. Например, мы в query string делаем запрос image.png.

POST /image.png HTTP/1.1

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

  • 130 курсов, 2000+ часов теории
  • 1000 практических заданий в браузере
  • 360 000 студентов

Электронная почта *

Отправляя форму, вы принимаете «Соглашение об обработке персональных данных» и условия «Оферты», а также соглашаетесь с «Условиями использования»

Наши выпускники работают в компаниях:

Выполнение запросов HTTP и HTTPS

СледующийПредыдущий

OS X и iOS предоставляют ряд API-интерфейсов общего назначения для выполнения запросов HTTP и HTTPS. С помощью этих API вы можете загружать файлы на диск, выполнять простые запросы HTTP и HTTPS или точно настраивать запрос в соответствии с конкретными требованиями инфраструктуры вашего сервера.

При выборе API вы должны сначала подумать, почему вы делаете HTTP-запрос:

  • Если вы пишете приложение для газетного киоска, вам следует использовать0011 NKAssetDownload

    API для загрузки содержимого в фоновом режиме.

  • Если вам нужно загрузить файл на диск в OS X, проще всего использовать класс NSURLDownload . Дополнительные сведения см. в разделе Загрузка содержимого URL-адреса на диск.

  • Вы должны использовать CFHTTPStream , если верно любое из следующих условий:

    • У вас есть строгое требование не использовать Objective-C.

    • Вам необходимо переопределить настройки прокси.

    • Вы должны быть совместимы с конкретным несовместимым сервером.

    Дополнительные сведения см. в разделе Создание запросов с помощью Core Foundation.

  • В противном случае обычно следует использовать API NSURLSession или NSURLConnection .

В следующих разделах эти API описаны более подробно.

Примечание:  Если у вас есть особые потребности, вы также можете написать собственную реализацию HTTP-клиента с помощью API-интерфейсов сокетов или потоков сокетов. Эти API описаны в разделе Использование сокетов и потоков сокетов.

Выполнение запросов с использованием Foundation

В следующих задачах описываются общие операции с классом NSURLSession , классом NSURLConnection и связанными классами.

Получение содержимого URL-адреса без делегатов

Если вам просто нужно получить содержимое URL-адреса и что-то сделать с результатами в конце, в OS X v10.9 и более поздних версиях или iOS 7 и более поздних версиях вы должны использовать класс NSURLSession . Вы также можете использовать Класс NSURLConnection для совместимости с более ранними версиями OS X и iOS.

Чтобы сделать это, позвоните по одному из следующих методов: DataTaskWithRequest: opplionHandler: ( NSURLSession ), DataStaskWithurl: opplionHandler: ( NSURLSession ), или SendAsynChestrecestreceest: QueplionSection: QueplionSection: QueplionSection. ). Ваше приложение должно предоставить следующую информацию:

  • В зависимости от обстоятельств либо NSURL или заполненный объект NSURLRequest , который предоставляет URL-адрес, данные тела и любую другую информацию, которая может потребоваться для вашего конкретного запроса.

  • Блок обработчика завершения, который запускается при завершении или сбое передачи.

  • Для NSURLConnection очередь NSOperation , в которой должен выполняться ваш блок.

Если передача прошла успешно, содержимое запроса передается в блок обработчика обратного вызова в виде объект NSData и объект NSURLResponse для запроса. Если системе загрузки URL-адреса не удается получить содержимое URL-адреса, в качестве третьего параметра передается объект NSError .

Получение содержимого URL-адреса с помощью делегатов

Если вашему приложению требуется больший контроль над вашим запросом, например контроль за перенаправлениями, выполнение пользовательской аутентификации или получение данных по частям по мере их получения, вы можете использовать Класс NSURLSession с пользовательским делегатом. Для совместимости с более ранними версиями OS X и iOS можно также использовать класс NSURLConnection с настраиваемым делегатом.

По большей части классы NSURLSession и NSURLConnection работают одинаково на высоком уровне. Однако есть несколько существенных отличий:

  • API NSURLSession обеспечивает поддержку задач загрузки, которые ведут себя так же, как .0011 NSURLЗагрузить класс . Это использование описано далее в разделе «Загрузка содержимого URL-адреса на диск».

  • При создании объекта NSURLSession вы предоставляете повторно используемый объект конфигурации, который инкапсулирует многие общие параметры конфигурации. С NSURLConnection вы должны установить эти параметры для каждого соединения независимо.

  • Объект NSURLConnection обрабатывает один запрос и любые последующие запросы.

    Объект NSURLSession управляет несколькими задачами, каждая из которых представляет собой один запрос URL и любые последующие запросы. Обычно вы создаете сеанс при запуске приложения, а затем создаете задачи почти так же, как вы создаете объекты NSURLConnection .

  • С NSURLConnection каждый объект соединения имеет отдельного делегата. С NSURLSession делегат используется всеми задачами в сеансе. Если вам нужно использовать другого делегата, вы должны создать новый сеанс.

При инициализации объекта NSURLSession или NSURLConnection подключение или сеанс автоматически планируется в текущем цикле выполнения в режиме цикла выполнения по умолчанию.

Предоставленный вами делегат получает уведомления на протяжении всего процесса подключения, включая прерывистые вызовы метода URLSession:dataTask:didReceiveData: или connection:didReceiveData: , когда соединение получает дополнительные данные с сервера. Ответственность за отслеживание уже полученных данных лежит на делегате, если это необходимо. Как правило:

  • Если данные можно обрабатывать по частям, сделайте это. Например, вы можете использовать потоковый синтаксический анализатор XML.

  • Если данных мало, вы можете добавить их к объекту NSMutableData .

  • Если данные большие, их следует записать в файл и обработать после завершения передачи.

При вызове метода URLSession:task:didCompleteWithError: или connectionDidFinishLoading: делегат получил все содержимое URL-адреса.

Загрузка содержимого URL-адреса на диск

В OS X v10.9 и более поздних версиях или iOS 7 и более поздних версиях, если вам необходимо загрузить URL-адрес и сохранить результаты в виде файла, но не нужно обрабатывать данные в Flight класс NSURLSession позволяет загрузить URL-адрес непосредственно в файл на диске за один шаг (в отличие от загрузки URL-адреса в память и последующей записи самостоятельно). Класс NSURLSession также позволяет приостанавливать и возобновлять загрузку, перезапускать неудачную загрузку и продолжать загрузку, когда приложение приостановлено, аварийно завершено или не работает по другой причине.

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

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

В более старых версиях iOS необходимо использовать Объект NSURLConnection , чтобы загрузить данные в память, а затем самостоятельно записать данные в файл.

Чтобы использовать класс NSURLSession для загрузки, ваш код должен выполнить следующее: приложение не запущено, вы должны указать объект конфигурации фонового сеанса (с уникальным идентификатором) при создании сеанса.

  • Если вам не нужна фоновая загрузка, вы можете создать сеанс, используя любой из предоставленных типов объектов конфигурации сеанса.

  • Создание и возобновление одной или нескольких задач загрузки в рамках сеанса.

  • Дождитесь, пока ваш делегат получит вызовы от задачи или сеанса. В частности, вы должны реализовать метод URLSession:downloadTask:didFinishDownloadingToURL: , чтобы что-то сделать с файлом, когда загрузка завершится и 0011 URLSession:task:didCompleteWithError: вызов для обработки любых ошибок.

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

    Выполнение POST-запроса

    Вы можете сделать HTTP- или HTTPS-запрос POST почти так же, как и любой другой запрос URL-адреса (описано в разделе Получение содержимого URL-адреса с делегатами). Основное отличие состоит в том, что сначала необходимо настроить Объект NSMutableURLRequest , который вы предоставляете методу initWithRequest:delegate: .

    Вам также необходимо создать данные тела. Это можно сделать одним из трех способов:

    • Для загрузки коротких данных в памяти необходимо закодировать URL-адрес существующей части данных. Этот процесс описан в разделе Кодирование данных URL.

    • Для загрузки данных файла с диска вызовите метод setHTTPBodyStream: , чтобы сообщить NSMutableURLRequest для чтения из NSInputStream и использования полученных данных в качестве содержимого тела.

    • Для больших блоков сконструированных данных вызовите CFStreamCreateBoundPair , чтобы создать пару потоков, затем вызовите метод setHTTPBodyStream: , чтобы указать NSMutableURLRequest использовать один из этих потоков в качестве источника для основного содержимого. Записывая в другой поток, вы можете отправлять данные по частям.

      В зависимости от того, как вы обрабатываете вещи на стороне сервера, вы также можете захотеть URL-кодировать данные, которые вы отправляете. )

    Чтобы указать другой тип содержимого для запроса, используйте метод setValue:forHTTPHeaderField: . Если вы это сделаете, убедитесь, что данные вашего тела правильно отформатированы для этого типа контента.

    Чтобы получить оценку хода выполнения запроса POST, реализуйте метод connection:didSendBodyData:totalBytesWritten:totalBytesExpectedToWrite: в делегате соединения.

    Настройка аутентификации

    Выполнение аутентификации с помощью NSURLSession и NSURLConnection относительно просты. То, как вы это сделаете, зависит от класса, который вы используете, и от версии OS X или iOS, на которую вы ориентируетесь.

    Для класса NSURLSession ваш делегат должен реализовать метод URLSession:task:didReceiveChallenge:completionHandler: . В этом методе вы выполняете любые операции, необходимые для определения того, как реагировать на вызов, затем вызываете предоставленный обработчик завершения с константой, указывающей, как должна действовать система загрузки URL-адресов, и, при необходимости, с учетными данными для использования в целях аутентификации.

    Для класса NSURLConnection :

    • В OS X v10.7 и новее или iOS 5 и новее ваш делегат должен реализовать метод connection:willSendRequestForAuthenticationChallenge: . Этот метод должен вызывать метод отправителя (объект NSURLConnection ), чтобы сообщить ему, как действовать дальше.

    • В более ранних версиях ваш делегат должен реализовать соединение :canAuthenticateAgainstProtectionSpace: и 9.0011 соединение: сделал вызов аутентификации: методов.

      Метод connection:didReceiveAuthenticationChallenge: эквивалентен методу connection:willSendRequestForAuthenticationChallenge: в более поздних версиях и вызывает метод отправителя ( объект NSURLConnection ), чтобы сообщить ему, как действовать дальше.

      Соединение : canAuthenticateAgainstProtectionSpace: метод должен возвращать YES , если [protectionSpace authenticationMethod] is any of NSURLAuthenticationMethodDefault , NSURLAuthenticationMethodHTTPBasic , NSURLAuthenticationMethodHTTPDigest , NSURLAuthenticationMethodHTMLForm , NSURLAuthenticationMethodNegotiate , or NSURLAuthenticationMethodNTLM .

    Возможные ответы на запрос аутентификации

    Независимо от того, какой класс вы используете, ваш метод обработчика аутентификации должен проверить запрос аутентификации и сообщить системе загрузки URL, как действовать:

    • Чтобы предоставить учетные данные для аутентификации, передайте NSURLSessionAuthChallengeUseCredential в качестве диспозиции (для NSURLSession ) или вызовите useCredential:forAuthenticationChallenge: 9012NSURL11 (для ).

      Сведения о создании объекта учетных данных см. в разделе Создание объекта учетных данных.

    • Чтобы продолжить запрос без аутентификации, передайте NSURLSessionAuthChallengeUseCredential в качестве расположения с учетными данными nil (для NSURLSession ) или вызовите continueWithoutCredentialForAuthenticationChallenge: (для NSURLConnection ).

    • Чтобы отменить вызов проверки подлинности, передайте NSURLSessionAuthChallengeCancelAuthenticationChallenge в качестве решения (для NSURLSession ) или вызовите cancelAuthenticationChallenge:

      0SURL. Если вы отмените запрос аутентификации, будет вызван метод ошибки делегата потока.

    • , чтобы сообщить операционной системе, чтобы справиться с этой задачей, как обычно, пройдите NSURLSessionAuthchallengeperformdefaulthandling в качестве диспозиции (для nsurlsession ) или вызовать . Если вы запрашиваете обработку по умолчанию, операционная система отправляет любые соответствующие учетные данные, которые существуют в кэше учетных данных.

    • Чтобы отклонить определенный тип аутентификации в процессе согласования с намерением принять другой метод, пройдите NSURLSessionAuthChallengeRejectProtectionSpace в качестве расположения (для NSURLSession ) или вызовите rejectProtectionSpaceAndContinueWithChallenge: (для NSURLConnection ).

    Создание объекта учетных данных

    В рамках метода подключения вашего делегата: willSendRequestForAuthenticationChallenge: или connection:didReceiveAuthenticationChallenge: вам может потребоваться предоставить фактическую информацию об аутентификации NSURLC2.

    • Для простой аутентификации по логину/паролю вызовите credentialWithUser:password:persistence: .

    • Для проверки подлинности на основе сертификата вызовите credentialWithIdentity:certificates:persistence: с объектом SecIdentityRef (который обычно получается из цепочки ключей пользователя путем вызова SecItemCopyMatching ).

    Дополнительная информация

    Чтобы узнать больше о NSURLSession API, прочитайте Руководство по программированию системы загрузки URL . Связанный пример кода см. в статьях SimpleURLConnections , AdvancedURLConnections и SeismicXML: использование NSXMLParser для анализа XML-документов .

    Для получения подробной информации об API NSURLConnection см. Руководство по программированию системы загрузки URL .

    Дополнительные сведения об использовании API NSStream для выполнения HTTP-запросов см. в разделе Настройка потоков сокетов в разделе 9.0477 Руководство по потоковому программированию .

    Пример метода setHTTPBodyStream: и функции CFStreamCreateBoundPair см. в SimpleURLConnections в библиотеке iOS. (Образец в целом предназначен для сборки и запуска на iOS, но сетевые части кода также полезны в OS X.) Foundation тесно связан с тем, что доступно на уровне Foundation. Таким образом, примеры из раздела «Выполнение запросов с использованием Foundation» должны помочь понять, как делать запросы с помощью CFHTTPStream API.

    Утилиты доступа к URL-адресам Core Foundation — это API на языке C, который является частью инфраструктуры Core Foundation. Чтобы узнать больше, прочтите Core Foundation URL Access Utilities Reference .

    API CFHTTPStream — это API на языке C, который является частью инфраструктуры Core Foundation. (Конечно, вы можете использовать его в коде Objective-C. ) Чтобы узнать больше, прочитайте Общение с HTTP-серверами и Общение с аутентификацией HTTP-серверов в Руководство по программированию CFNetwork .

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

    Работа с веб-службами

    Если вы включаете взаимодействие веб-сервисов на стороне клиента в свою программу OS X, вы можете воспользоваться рядом технологий:

    • Класс NSJSONSerialization преобразует собственные объекты Cocoa в нотацию объектов JavaScript (JSON).

    • Класс NSXMLParser предоставляет Cocoa API для синтаксического анализа содержимого XML в стиле SAX (потоковое).

    • Библиотека libxml2 предоставляет кросс-платформенный C API для анализа содержимого XML в стиле SAX (потоковая передача) и в стиле DOM (на основе дерева). Документацию по libxml2 см. на http://xmlsoft.org/.

    • API NSXMLDocument (только в OS X) обеспечивает поддержку XML-содержимого в стиле DOM.

    Кроме того, существует ряд сторонних библиотек для работы с веб-сервисами.

    Важно:  Среда Web Services Core устарела и не должна использоваться для новой разработки.

    СледующийПредыдущий




    Авторские права © Apple Inc., 2004, 2017. Все права защищены. Условия использования | Политика конфиденциальности | Обновлено: 27.03.2017

    Различные типы HTTP-запросов

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

    GET, POST, PUT, PATCH и DELETE . Они эквивалентны операциям CRUD (создание, чтение, обновление и удаление) .

    GET: GET-запрос используется для чтения/получения данных с веб-сервера. GET возвращает код состояния HTTP 200 (ОК) , если данные успешно получены с сервера.

    POST: POST-запрос используется для отправки данных (файл, данные формы и т. д.) на сервер. При успешном создании он возвращает код состояния HTTP 201 .

    PUT: Запрос PUT используется для изменения данных на сервере. Он заменяет весь контент в определенном месте данными, которые передаются в полезной нагрузке тела. Если ресурсов, соответствующих запросу, нет, он будет сгенерирован.

    PATCH: PATCH похож на запрос PUT, но с той лишь разницей, что он изменяет часть данных. Он заменит только тот контент, который вы хотите обновить.

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

    Теперь давайте разберемся со всеми этими методами запроса на примере. Мы создали небольшое приложение, включающее сервер NodeJS и базу данных MongoDB. Сервер NodeJS будет обрабатывать все запросы и возвращать соответствующий ответ .

    Настройка и установка:

    Шаг 1: Чтобы запустить приложение NodeJS, создайте папку с именем RestAPI и выполните следующую команду.

     npm init -y 

    Шаг 2: С помощью следующей команды установите необходимые пакеты npm.

     npm install express body-parser mongoose 

    Шаг 3: В каталоге проекта создайте файл с именем index.js.

    Структура проекта: Теперь каталог нашего проекта должен выглядеть так.

     

    Как сделать запрос GET

    1. Чтобы сделать запрос GET, вставьте следующий URL-адрес в текстовое поле Введите URL-адрес запроса почтальона.

     https://api.github.com/gists 

    2. Перейдите на вкладку заголовков и добавьте заголовок «Принять» и установите для него значение:

     application/vnd.github.v3+json 

    3. Внизу вы можете увидеть ответ в формате JSON.

     

    Как сделать запрос POST

    Шаги для отправки запроса POST:

    Шаг 1: Войдите в свою учетную запись GitHub и перейдите в Настройки/Настройки разработчика >> Токены личного доступа .

    Шаг 2: Нажмите кнопку «Создать новый токен».

     

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

     

     

    Шаг 4: Нажмите кнопку «Создать токен».

     

    Шаг 5: Скопируйте код доступа и вставьте куда-нибудь.

     

    Шаг 6: Наконец, мы готовы сделать запрос POST. Вставьте тот же URL-адрес, который мы использовали выше в запросе GET, в поле ввода почтальона.

    Шаг 7: На вкладке заголовков добавьте «Принять» в качестве заголовка и установите для него значение:

     application/vnd.github.v3+json 

    Шаг 8: Перейдите на вкладку body , выберите тип содержимого JSON и выберите необработанный формат данных.

    Шаг 9: Вставьте следующее на вкладке body.

     {
        «публичный»: правда,
            "файлы": {
            "newgist.txt": {
                "content": "Добавление GIST через API!!"
            }
        }
    } 

    Сначала в приведенном выше тексте мы установили общедоступный флаг на true , что указывает на то, что суть, которую мы создаем, общедоступна. Во-вторых, мы определили свойство файлов , значением которого является другой объект с ключом имени вашего нового содержания. Внутри нового объекта gist у нас есть еще один ключ с именем content , значением которого является то, что вы хотите написать в своем gist.

     

    Шаг 10: Перейдите на вкладку авторизация и выберите тип авторизации на Basic Auth . Введите свое имя пользователя GitHub и сгенерированный токен доступа в поля имени пользователя и пароля соответственно.

     

    Шаг 11: Нажмите кнопку отправки, и вы получите ответ.

     

    Как сделать запрос PATCH

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

    Шаг 1: Найдите идентификатор вашего созданного объекта, перейдя по адресу

     https://gist.github.com 

     

     

    Шаг 2: Вставьте следующий URL-адрес в поле ввода почтальона.

     https://api.github. com/gists/{gist_id} 

    Шаг 3: На вкладке заголовков добавьте «Принять» в качестве заголовка и установите для него

     application/vnd. github.v3+json 

    Шаг 4: Перейдите на вкладку body и добавьте описание созданного объекта.

     {
        "описание": это моя недавно созданная суть,
            "файлы": {
            "newgist.txt": {
                "content": "Добавление GIST через API!!"
            }
        }
    } 

    Шаг 5: Перейдите на вкладку авторизации и выберите тип авторизации на Basic Auth . Введите свое имя пользователя GitHub и сгенерированный токен доступа в поля имени пользователя и пароля соответственно.

    Шаг 6: Нажмите кнопку отправки и обновите суть, чтобы увидеть обновленное описание.

     

    Как сделать запрос на удаление

    Шаг 1: Вставьте следующий URL-адрес в поле ввода почтальона.