Как подключаться к HTTP-серверу с помощью Windows.Web.Http (HTML)
[ Эта статья адресована разработчикам приложений среды выполнения Windows для Windows 8.x и Windows Phone 8.x. При разработке приложений для Windows 10 см. раздел последняя документация]
Отправка запроса GET в веб-службу и получение ответа с помощью класса Windows.Web.Http.HttpClient в пространстве имен Windows.Web.Http.
(Получите пример HTTPClient.)
Классы в пространстве имен Windows.Web.Http предоставляют программный интерфейс для современных клиентских приложений HTTP. Пространство имен Windows.Web.Http и связанные с ним пространства имен Windows.Web.Http.Headers и Windows.Web.Http.Filters предоставляют клиентские компоненты HTTP, которые позволяют пользователям совершать HTTP-запросы и получать HTTP-ответы от современных веб-служб по протоколу HTTP.
В Windows 8.1 появилось Windows.Web.Http — пространство имен среды выполнения Windows для использования в приложениях для Windows, которые подключаются к веб-службам HTTP и REST. Этот новый API обеспечивает полную поддержку функций во всех поддерживаемых языках и приходит на смену API HTTP, первоначально выпущенному для Windows 8.
Новый API заменяет три разных API с разными функциями, которые ранее были необходимы для проекции на каждый язык в Windows 8.
- WinJS.xhr для JavaScript
- System.Net.Http.HttpClient в пространстве имен System.Net.Http для C# и VB.Примечание Не поддерживается в Windows Phone.
- XML HTTP Extended Request (IXMLHTTPRequest2) для C++
Для базовых операций запроса у нового API есть простой интерфейс для обработки наиболее распространенных задач. Также предоставляются допустимые значения по умолчанию для проверки подлинности (AUTH), применимые к большинству сценариев. Для более сложных операций HTTP доступны дополнительные возможности:
методы для распространенных команд (DELETE, GET, PUT и POST);
поддержка распространенных параметров и схем проверки подлинности;
доступ к сведениям о передаче по протоколу SSL;
возможность включать пользовательские фильтры в расширенные приложения;
возможность получать, задавать и удалять файлы cookie;
информация о ходе выполнения HTTP-запроса доступна для асинхронных методов.
Класс Windows.Web.Http.HttpClient предназначен для отправки и получения базовых запросов по HTTP. Он служит базовым классом для отправки HTTP-запросов и получения HTTP-ответов от ресурса, определяемого по универсальному коду ресурса (URI). Этот класс можно использовать для отправки запросов GET, PUT, POST, DELETE, а также других запросов в веб-службу. Каждый из этих запросов отправляется как асинхронная операция.
Класс Windows.Web.Http.HttpRequestMessage представляет сообщение HTTP-запроса, отправляемое объектом Windows.Web.Http.HttpClient. Класс Windows.Web.Http.HttpResponseMessage представляет сообщение HTTP-ответа, полученного в ответ на HTTP-запрос. Сообщения HTTP определены IETF в RFC 2616.
Пространство имен Windows.Web.Http предоставляет ряд классов, представляющих содержимое HTTP (основной текст и заголовки содержимого, включая файлы cookie), связанное с HTTP-запросом или HTTP-ответом. Эти различные классы позволяют использовать в содержимом буфер, строку, поток и данные в формате "имя-значение", закодированные типами MIME application/x-www-form-urlencoded, multipart/* и multipart/form-data. Также можно определять настраиваемое содержимое.
В этом примере класс HttpStringContent представляет HTTP-ответ в виде строки.
Пространство имен Windows.Web.Http.Headers поддерживает создание заголовков HTTP и файлов cookie, которые затем связываются в качестве свойств с объектами HttpRequestMessage и HttpResponseMessage.
Необходимые условия
Следующие примеры этого раздела написаны на JavaScript и HTML. Необходимы базовые знания HTTP-запросов, описанных в стандарте RFC 2616.
В приложении на JavaScript и HTML также можно создавать HTTP-запросы с помощью WinJS.xhr и XMLHttpRequest. Дополнительные сведения см. в разделе Подключение к веб-службам (приложения среды выполнения Windows на JavaScript и HTML).
Инструкции
Этап 1: Создание нового проекта
- Откройте Microsoft Visual Studio 2013 и выберите пункт Создать проект в меню Файл.
- В списке шаблонов выберите JavaScript.
- В разделе выберите Store apps.
- В этом разделе выберите Universal Apps, Windows apps или Windows Phone apps (в зависимости от целевой платформы), а затем — Пустое приложение.
- Назовите приложение
HttpClientGet
и нажмите кнопку ОК.
Этап 2: Задание возможностей для обеспечения доступа к сети
Задайте сетевые возможности вашего приложения, чтобы обеспечить доступ к частной домашней или рабочей сети и к Интернету. Необходимо включить сетевые возможности приложения, чтобы клиент мог подключаться к веб-службам.
Чтобы подключить приложение, использующее Windows.Web.Http.HttpClient, к веб-службе на другом компьютере, понадобится задать сетевые возможности. Чтобы приложение могло подключаться как клиент к веб-службам в Интернете, необходима возможность Интернет (клиент). Если приложению необходима возможность подключаться от имени клиента к веб-службам в домашней или рабочей сети, то потребуется возможность Частные сети (клиент и сервер).
Примечание В Windows Phone используется единственная возможность сети Интернет (клиент и сервер) для обеспечения всех функций доступа приложения к сети.
Если веб-служба работает на том же компьютере, что и приложение, потребуется замыкание на себя. Приложения, разработанные и выполняемые в Visual Studio 2013, будут автоматически регистрироваться как исключенные из ограничений замыкания на себя. Дополнительная информация: Как включить замыкание на себя и устранить неполадки сетевой изоляции.
Дополнительные сведения о доступе к сети см. в разделе Как настроить возможности сети.
Эти действия нужны, чтобы настроить перед развертыванием возможности сети для приложения, если оно обращается к веб-службе в Интернете либо в частной или в рабочей сети.
Откройте файл package.appxmanifest в Visual Studio 2013.
Перейдите на вкладку Возможности.
Для сборки версии примера для Windows выберите возможности Интернет (клиент) и Частные сети (клиент и сервер).
Для сборки версии примера для Windows Phone выберите возможность Интернет (клиент и сервер).
Сохраните и закройте файл манифеста.
Этап 3: Добавление пользовательского интерфейса на HTML
В этом разделе мы определим макет приложения на HTML, чтобы указать приблизительный размер и положение каждого объекта в приложении. Мы также завершим пользовательский интерфейс приложения, добавив элементы управления и содержимое для отображения данных.
В этом примере использованы простые элементы пользовательского интерфейса HTML, которые включают:
Элемент управления с объектом class используется для текстовой подписи и поля ввода для входного адреса URI, а элемент управления button запускает асинхронный метод.
Элемент управления с объектом class, с текстовой подписью и текстовым полем для отображения текущего состояния. Здесь будут отображаться сообщения о состоянии и об ошибках. Этот элемент управления также содержит объект class, в котором отображаются данные, полученные от веб-службы. В этом примере результат HTTP-операции GET отображается как обычный текст, содержащий разметку HTML.
Откройте папку js, откройте существующий файл default.js и добавьте в него следующие элементы пользовательского интерфейса.
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>HttpClientGet</title> <!-- WinJS references - Windows --> <link href="//Microsoft.WinJS.2.0/css/ui-dark.css" rel="stylesheet" /> <script src="//Microsoft.WinJS.2.0/js/base.js"></script> <script src="//Microsoft.WinJS.2.0/js/ui.js"></script> <!-- WinJS references - Phone --> <link href="/css/ui-themed.css" rel="stylesheet" /> <script src="//Microsoft.Phone.WinJS.2.1/js/base.js"></script> <script src="//Microsoft.Phone.WinJS.2.1/js/ui.js"></script> <!-- HttpClientGet references --> <link href="/css/default.css" rel="stylesheet" /> <script src="/js/default.js"></script> <script src="/js/mainpage.js"></script> </head> <body> <div data-win-control="SampleInput"> <p> Download the contents of a page and display it. </p> <p class="clear"> <label for="inputAddress">URI Address:</label> <input type="text" id="inputAddress" value="https://www.contoso.com" /> </p> <p> <button id="startButton">Start</button> </p> </div> <div data-win-control="SampleOutput"> <p class="clear"> <label for="statusText">Status:</label> <input type="text" id="statusText" value="" /> </p> <textarea id="outputView"></textarea> </div> </body> </html>
Этап 4: Создание HttpClient
Сначала создайте объект Windows.Web.Http.HttpClient и добавьте заголовок user-agent.
По умолчанию объект HttpClient не отправляет заголовок user-agent с HTTP-запросом в веб-службу. Некоторые HTTP-серверы, включая некоторые веб-серверы Майкрософт, требуют, чтобы HTTP-запрос, отправляемый клиентом, содержал заголовок user-agent. Если заголовок отсутствует, HTTP-сервер возвращает ошибку. Для добавления заголовка user-agent используются классы из пространства имен Windows.Web.Http.Headers. Чтобы избежать таких ошибок, добавьте этот заголовок в свойство HttpClient.DefaultRequestHeaders.
Откройте папку js, добавьте новый файл mainpage.js, а затем добавьте в него следующий код.
(function () { "use strict"; var httpClient; var httpPromise; var page = WinJS.UI.Pages.define("/html/mainpage.html", { ready: function (element, options) { document.getElementById("startButton").addEventListener("click", start, false); httpClient = new Windows.Web.Http.HttpClient(); // Add a user-agent header headers = httpClient.defaultRequestHeaders; // UserAgent is a HttpProductInfoHeaderValueCollection // A collection of HttpProductInfoHeaderValue items // The safe way to check a header value from the user is the TryParseAdd method // Since we know this header is okay, we use ParseAdd with will throw an exception // with a bad value headers.userAgent.parseAdd("ie"); headers.userAgent.parseAdd("Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; WOW64; Trident/6.0)"); } }); })();
Откройте папку js и файл default.js, а затем добавьте в него следующий код.
(// For an introduction to the Blank template, see the following documentation: // https://go.microsoft.com/fwlink/p/?LinkID=232509 (function () { "use strict"; var app = WinJS.Application; var activation = Windows.ApplicationModel.Activation; app.onactivated = function (args) { if (args.detail.kind === activation.ActivationKind.launch) { if (args.detail.previousExecutionState !== activation.ApplicationExecutionState.terminated) { startButton.onclick = start; } else { startButton.onclick = start; } args.setPromise(WinJS.UI.processAll()); } }; app.oncheckpoint = function (args) { // This application is about to be suspended. Save any state // that needs to persist across suspensions here. You might use the // WinJS.Application.sessionState object, which is automatically // saved and restored across suspension. If you need to complete an // asynchronous operation before your application is suspended, call // args.setPromise(). }; app.start(); })();
Этап 5: Отправка запроса GET и получение ответа
При нажатии кнопки Start мы сначала проверяем допустимость URI, указанного в элементе inputAddress. Затем мы отправляем запрос GET по этому URI и ожидаем ответа от HTTP-сервера.
Основная часть работы выполняется обработчиком щелчков для элемента Button Start (Запуск). Когда нажимается эта кнопка, текст в элементах пользовательского интерфейса statusText и outputView обновляется. Сначала проверяется входной адрес URI, чтобы убедиться, что пользователь предоставил допустимый адрес URI. Если имеется допустимый URI от пользователя, то приложение отправляет HTTP-запрос GET по указанному URI и ожидает HTTP-ответа. При ошибке или исключении результат отображается в элементе пользовательского интерфейса statusText. Если ошибки не происходят, то ответ веб-службы отображается в элементе пользовательского интерфейса outputView.
Исключение создается, если конструктору объекта Windows.Foundation.Uri передается недопустимая строка для универсального кода ресурса (URI).
В JavaScript нет метода для преобразования строки в код URI. В этом случае для перехвата исключения поместите код, в котором создается URI, в блок try-catch.
В примере также проверяется схема HTTP в URI (HTTP или HTTPS), поскольку Windows.Web.Http.HttpClient поддерживает только эти две схемы.
Ключевые слова JavaScript then и done делают код, асинхронно отправляющий запрос GET и получающий ответ, похожим на код, который выполняет эту операцию синхронно.
Исключения из-за сетевых ошибок (потеря подключения, ошибки подключения, ошибки HTTP-сервера и др.) могут возникать в любое время. Из-за таких ошибок создаются исключения. Если ваше приложение не обрабатывает исключение, то среда выполнения может завершить работу приложения. При вызове большинства асинхронных сетевых методов вы должны указать код для обработки исключений. Иногда, когда возникает исключение, можно снова вызвать сетевой метод и устранить проблему. В других случаях приложение должно быть готово продолжить работу без подключения к сети, используя данные из кэша. Дополнительные сведения об обработке сетевых исключений см. в разделе Обработка исключений в сетевых приложениях.
Метод HttpResponse.EnsureSuccessStatusCode создает исключение, если веб-сервер возвращает для запроса код состояния ошибки со значением HttpResponse.StatusCode вне диапазона Successful (200–299). Для всех исключений используйте блок try-catch и при ошибке выводите сообщение об исключении в элементе пользовательского интерфейса statusText.
Свойство HttpResponse.Content представляет содержимое HTTP-ответа. Метод HttpClient.GetAsync(Uri) считывает содержимое HTTP в строку в рамках асинхронной операции. Мы заменяем все теги <br> в возвращенном тексте HTML на символы новой строки для удобства отображения. Если метод завершается успешно, мы отображаем значение HttpResponse.StatusCode в элементе пользовательского интерфейса statusText, а объект HttpResponse.Content, возвращенный веб-службой, отображаем в элементе outputView.
Откройте папку js и добавьте следующий код в файл mainpage.js.
function start() { var response = new Windows.Web.Http.HttpResponseMessage(); var statusText = document.getElementById("statusText"); var outputView = document.getElementById("outputView"); // The value of 'inputAddress' is set by the user // and is therefore untrusted input. // If we can't create a valid absolute URI, // We notify the user about the incorrect input. statusText.Text = "Testing URI is valid."; var uriString = document.getElementById("inputAddress").value.trim(); if (!uriString) { return; } var resourceUri; try { resourceUri = new Windows.Foundation.Uri(uriString); } catch (Exception) { statusText.Text = "Invalid URI, please re-enter a valid URI."; return; } if (resourceUri.schemeName != "http" && resourceUri.schemeName != "https") { statusText.Text = "Only 'http' and 'https' schemes supported. Please re-enter URI"; return; } var responseBodyAsText=""; outputView.Text = ""; statusText.Text = "Waiting for response ..."; httpPromise = httpClient.getAsync(resourceUri).then(function (response) { outputStatus = response.statusCode + " " + response.reasonPhrase; response.EnsureSuccessStatusCode(); response.content.readAsStringAsync().then(function (responseBodyAsText) { // Format the HTTP response to display better responseBodyAsText = responseBodyAsText.replace(/<br>/g, "\r\n"); outputView.value = responseBodyAsText; return response; }); )}; httpPromise.done(function (response) { statusText.value = response.StatusCode + " " + response.ReasonPhrase + "\r\n"; }, onError); function onError(error) { statusText.value = "Error = " + error.number + " Message: " + error.message; } })();
Объект Windows.Web.Http.HttpClient использует WinInet для отправки HTTP-запросов и запросов веб-службы, а также для получения ответов. Время ожидания, используемое WinInet для операции подключения HTTP, по умолчанию составляет 60 секунд. Если HTTP-сервер или веб-служба временно недоступны либо блокируются брандмауэром и сервер не отвечает на запрос Windows.Web.Http.HttpClient, то WinInet по умолчанию ожидает 60 секунд, а затем возвращает ошибку, которая создает исключение в приложении. Если запрос имени HTTP-сервера возвращает несколько IP-адресов, то перед завершением с ошибкой WinInet проверяет каждый из дополнительных IP-адресов для сайта, по умолчанию ожидая ответа по каждому адресу в течение 60 секунд. Приложение, создающее HTTP-запрос или запрос веб-службы, может ожидать несколько минут, повторяя попытки с несколькими IP-адресами, прежде чем WinInet возвращает ошибку и создается исключение. Пользователю в этом случае может показаться, что приложение не работает. Время ожидания, используемое WinInet по умолчанию для операций отправки и получения после установления подключения, составляет 30 секунд.
Чтобы уменьшить влияние таких проблем и ускорить ответ приложения, можно сократить время ожидания для операций Windows.Web.Http.HttpClient, чтобы они завершались с ошибкой истечения времени ожидания раньше, чем при параметрах WinInet по умолчанию. Дополнительные сведения о настройке времени ожидания см. в разделах Установка значений времени ожидания с помощью WinJS.xhr или HttpClient и Задание времени ожидания в операциях с сокетом.
Замечания
В этом разделе мы рассмотрели, как использовать класс Windows.Web.Http.HttpClient, чтобы отправить запрос GET в веб-службу, и как получить ответ с помощью класса Windows.Web.Http.HttpResponseMessage и связанных классов из пространства имен Windows.Web.Http.Headers.
Связанные разделы
Другие ресурсы
Обработка исключений в сетевых приложениях
Как настроить возможности сети
Использование интерфейса замыкания на себя и отладка сетевой изоляции
Установка значений времени ожидания с помощью WinJS.xhr или HttpClient
Ссылки
Примеры