запросы — структура (заголовок и тело), методы, строка статуса и коды состояния, ответы
Большинство используемых нами веб- и мобильных приложений постоянно взаимодействуют с глобальной сетью. Почти все подобные коммуникации совершаются с помощью запросов по протоколу HTTP. Рассказываем о них подробнее.
Базово о протоколе HTTP
HTTP (HyperText Transfer Protocol, дословно — «протокол передачи гипертекста») представляет собой протокол прикладного уровня, используемый для доступа к ресурсам Всемирной Паутины. Под термином гипертекст следует понимать текст, в понятном для человека представлении, при этом содержащий ссылки на другие ресурсы.
Данный протокол описывается спецификацией RFC 2616. На сегодняшний день наиболее распространенной версией протокола является версия HTTP/2, однако нередко все еще можно встретить более раннюю версию HTTP/1.1.
В обмене информацией по HTTP-протоколу принимают участие клиент и сервер. Происходит это по следующей схеме:
- Клиент запрашивает у сервера некоторый ресурс.
- Сервер обрабатывает запрос и возвращает клиенту ресурс, который был запрошен.
По умолчанию для коммуникации по HTTP используется порт 80, хотя вместо него может быть выбран и любой другой порт. Многое зависит от конфигурации конкретного веб-сервера.
Подробнее о протоколе HTTP читайте по ссылке →
HTTP-сообщения: запросы и ответы
Данные между клиентом и сервером в рамках работы протокола передаются с помощью HTTP-сообщений. Они бывают двух видов:
- Запросы (HTTP Requests) — сообщения, которые отправляются клиентом на сервер, чтобы вызвать выполнение некоторых действий. Зачастую для получения доступа к определенному ресурсу. Основой запроса является HTTP-заголовок.
- Ответы (HTTP Responses) — сообщения, которые сервер отправляет в ответ на клиентский запрос.
Само по себе сообщение представляет собой информацию в текстовом виде, записанную в несколько строчек.
В целом, как запросы HTTP, так и ответы имеют следующую структуру:
- Стартовая строка (start line) — используется для описания версии используемого протокола и другой информации — вроде запрашиваемого ресурса или кода ответа. Как можно понять из названия, ее содержимое занимает ровно одну строчку.
- HTTP-заголовки (HTTP Headers) — несколько строчек текста в определенном формате, которые либо уточняют запрос, либо описывают содержимое тела сообщения.
- Пустая строка, которая сообщает, что все метаданные для конкретного запроса или ответа были отправлены.
- Опциональное тело сообщения, которое содержит данные, связанные с запросом, либо документ (например HTML-страницу), передаваемый в ответе.
Рассмотрим атрибуты HTTP-запроса подробнее.
Стартовая строка
Стартовая строка HTTP-запроса состоит из трех элементов:
- Метод HTTP-запроса (method, реже используется термин verb). Обычно это короткое слово на английском, которое указывает, что конкретно нужно сделать с запрашиваемым ресурсом. Например, метод GET сообщает серверу, что пользователь хочет получить некоторые данные, а POST — что некоторые данные должны быть помещены на сервер.
- Цель запроса. Представлена указателем ресурса URL, который состоит из протокола, доменного имени (или IP-адреса), пути к конкретному ресурсу на сервере. Дополнительно может содержать указание порта, несколько параметров HTTP-запроса и еще ряд опциональных элементов.
- Версия используемого протокола (либо 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, нет никакой разницы. Однако в названиях заголовков принято начинать каждое новое слово с заглавной буквы. Структура значения зависит от конкретного заголовка. Несмотря на то, что заголовок вместе со значениями может быть достаточно длинным, занимает он всего одну строчку.
В запросах может передаваться большое число различных заголовков, но все их можно разделить на три категории:
- Общего назначения, которые применяются ко всему сообщению целиком.
- Заголовки запроса уточняют некоторую информацию о запросе, сообщая дополнительный контекст или ограничивая его некоторыми логическими условиями.
- Заголовки представления, которые описывают формат данных сообщения и используемую кодировку. Добавляются к запросу только в тех случаях, когда с ним передается некоторое тело.
Ниже можно видеть пример заголовков в запросе:
Самые частые заголовки запроса
Заголовок | Описание |
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). На ней располагаются следующие элементы:
- Уже известная нам по стартовой строке запроса версия протокола (HTTP/2 или HTTP/1.1).
- Код состояния, который указывает, насколько успешно завершилась обработка запроса.
- Пояснение — короткое текстовое описание к коду состояния. Используется исключительно для того, чтобы упростить понимание и восприятие человека при просмотре ответа.
Так выглядит строка состояния ответа.
Коды состояния и текст статуса
Коды состояния 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, или заголовки ответа, используются для того, чтобы уточнить ответ, и никак не влияют на содержимое тела. Они существуют в том же формате, что и остальные заголовки, а именно «Имя-Значение» с двоеточием (:) в качестве разделителя.
Ниже приведены наиболее часто встречаемые в ответах заголовки:
Категория | Пример | Описание |
Server | Server: ngnix | Содержит информацию о сервере, который обработал запрос. |
Set-Cookie | Set-Cookie:PHPSSID=bf42938f | Содержит куки, требуемые для идентификации клиента. Браузер парсит куки и сохраняет их в своем хранилище для дальнейших запросов. |
WWW-Authenticate | WWW-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-запрос на сервер и получить ответ:
- Инструменты разработчика в браузере.
- Утилита 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>
В ответ мы получаем какие-то заголовки и далее идет тело, которое нас как раз и интересует. В данном случае это не какая-то страница нашего сайта, а просто страница, которую отдает сервер. Она связана с перенаправлением.
Если с заголовками все понятно, они отделяются друг от друга переводом строки и для отправки мы добавляем еще один перевод, который выглядит как пустая строка, то как быть с телом запроса? Оно может содержать внутри все что угодно.
Во время отправки ответа сервер формирует специальный заголовок, который называется Content-Length. Это и есть ключ к тому как работать с body. Перед тем как отправить тело ответа, происходит вычисление его длины и записывается количество байт.
# число — количество байт Content-Length: 218
После того, как передан такой заголовок, другая сторона будет ожидать ровно столько байт, сколько в нем указано.
Указание размера тела нужно не только для отправки ответа, но и при запросах, когда на сервер посылаются, например, данные формы.
Практика показывает, что не все серверы правильно работают при наличии только заголовка Content-Length. Им не хватает еще одного. Тип содержимого запроса или ответа, которое содержит
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 ofNSURLAuthenticationMethodDefault
,NSURLAuthenticationMethodHTTPBasic
,NSURLAuthenticationMethodHTTPDigest
,NSURLAuthenticationMethodHTMLForm
,NSURLAuthenticationMethodNegotiate
, orNSURLAuthenticationMethodNTLM
.
Возможные ответы на запрос аутентификации
Независимо от того, какой класс вы используете, ваш метод обработчика аутентификации должен проверить запрос аутентификации и сообщить системе загрузки URL, как действовать:
Чтобы предоставить учетные данные для аутентификации, передайте
NSURLSessionAuthChallengeUseCredential
в качестве диспозиции (дляNSURLSession
) или вызовитеuseCredential:forAuthenticationChallenge: 9012NSURL11 (для
).
Сведения о создании объекта учетных данных см. в разделе Создание объекта учетных данных.
Чтобы продолжить запрос без аутентификации, передайте
NSURLSessionAuthChallengeUseCredential
в качестве расположения с учетными даннымиnil
(дляNSURLSession
) или вызовитеcontinueWithoutCredentialForAuthenticationChallenge:
(дляNSURLConnection
).Чтобы отменить вызов проверки подлинности, передайте
0SURL. Если вы отмените запрос аутентификации, будет вызван метод ошибки делегата потока.NSURLSessionAuthChallengeCancelAuthenticationChallenge
в качестве решения (дляNSURLSession
) или вызовитеcancelAuthenticationChallenge:
, чтобы сообщить операционной системе, чтобы справиться с этой задачей, как обычно, пройдите
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: 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-адрес в поле ввода почтальона.