Пользовательское управление сетевыми запросами

Элемент управления Microsoft Edge WebView2 позволяет взаимодействовать с сетевыми запросами и изменять их. Вы можете предоставить ответ или изменить сетевой запрос с помощью WebResourceRequested событий and WebResourceResponseReceived .

С помощью этого NavigateWithWebResourceRequest метода можно перемещаться по определенным сетевым запросам.

Подробное содержание:

Введение

Элемент управления Microsoft Edge WebView2 позволяет взаимодействовать с сетевыми запросами и изменять их. Вы можете предоставить ответ или изменить сетевой запрос с помощью WebResourceRequested событий and WebResourceResponseReceived .

С помощью этого NavigateWithWebResourceRequest метода можно перемещаться по определенным сетевым запросам.

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

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

  • Блокировать содержимое на веб-странице, например определенные изображения.

  • Тонкая настройка проверки подлинности для определенных страниц.

Терминология:

Термин Определение
перехват Ваше ведущее приложение может перехватывать запрос, отправляемый из управления WebView2 на HTTP-сервер, считывать или изменять запрос, а затем отправлять неизменный или измененный запрос на HTTP-сервер (или локальный код вместо HTTP-сервера).
Переопределение Ваше ведущее приложение может переопределять ответ, отправляемый с сервера HTTP элементу управления WebView2, и отправлять пользовательский ответ элементу управления WebView2 вместо исходного ответа.

Когда следует использовать пользовательский или базовый подходы

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

Вместо использования API WebResourceRequested предпочтительнее использовать следующие подходы, когда это возможно:

Примечание. Для URL-адресов с виртуальными именами узлов использование события WebResourceRequested не поддерживается. Это вызвано тем, WebResourceRequested что событие не запускается для метода SetVirtualHostNameToFolderMapping.

Взаимодействие ведущего приложения, элемента управления WebView2 и HTTP-сервера

Элемент управления WebView2 находится между ведущим приложением и HTTP-сервером. Когда ваше ведущее приложение переходит к универсальному коду ресурса (URI), элемент управления WebView2 отправляет запрос на сервер HTTP. Затем HTTP-сервер отправляет ответ элементу управления WebView2.

Перехват запроса, его отслеживание или изменение

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

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

Ведущее приложение может изменять свойства запроса с помощью этого API:

Возможные действия с заголовками

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

Заголовок запроса можно использовать для указания формата ответа (например, Accept-* заголовков), установки маркеров проверки подлинности, чтения и записи файлов cookie (конфиденциальной информации), изменения агента пользователя и т. д. Заголовок отклика можно использовать для предоставления дополнительного контекста ответа.

Фильтрация события WebResourceRequested на основе URL-адреса и типа ресурса

Чтобы получать WebResourceRequested события, укажите фильтры для запросов, которые интересует ведущее приложение, на основе URL-адреса и типа ресурса.

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

Другой пример — если ведущее приложение заинтересовано только во всех запросах, которые находятся на сайте, например https://example.com. Затем приложение может указать фильтр URL-адресов для https://example.com/* получения событий, связанных с этим сайтом.

Подробные сведения о том, как работает фильтр URL-адресов, см. в разделе CoreWebView2.AddWebResourceRequestedFilter Замечания о методе >

Зачем перехватывать запросы, отправляемые из WebView2?

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

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

Последовательность изменения запросов

Схема последовательности для изменения запросов

  1. Ведущее приложение настраивает фильтр.WebResourceRequested
  2. Ведущее приложение определяет обработчики событий для WebResourceRequested и WebResourceResponseReceived.
  3. Ведущее приложение осуществляет переход по элементу управления WebView2 на веб-страницу.
  4. Элемент управления WebView2 создает запрос ресурса, необходимого для веб-страницы.
  5. Элемент управления WebView2 запускает WebResourceRequested событие для ведущего приложения.
  6. Ведущее приложение прослушивает и обрабатывает WebResourceRequested событие.
  7. Ведущее приложение может изменять заголовки на этом этапе. Ведущее приложение также может отложить WebResourceRequested событие, что означает, что ведущее приложение запрашивает дополнительное время, чтобы решить, что делать.
  8. Сетевой стек WebView2 может добавлять дополнительные заголовки (например, может добавлять файлы cookie и заголовки авторизации).
  9. Элемент управления WebView2 отправляет запрос на HTTP-сервер.
  10. HTTP-сервер отправляет ответ элементу управления WebView2.
  11. Элемент управления WebView2 активирует WebResourceResponseReceived событие.
  12. Ведущее приложение прослушивает WebResourceResponseReceived событие и обрабатывает его.

Пример: перехват запроса для его отслеживания или изменения

В следующем примере ведущее приложение перехватывает запрос документов, отправляемый из элемента управления WebView2 на http://www.example.com HTTP-сервер, добавляет пользовательское значение заголовка и отправляет запрос.

// Add a filter to select all resource types under http://www.example.com
webView.CoreWebView2.AddWebResourceRequestedFilter(
      "http://www.example.com/*", CoreWebView2WebResourceContext.All);
webView.CoreWebView2.WebResourceRequested += delegate (
   object sender, CoreWebView2WebResourceRequestedEventArgs args) {
   CoreWebView2WebResourceContext resourceContext = args.ResourceContext;
   // Only intercept the document resources
   if (resourceContext != CoreWebView2WebResourceContext.Document)
   {
      return;
   }
   CoreWebView2HttpRequestHeaders requestHeaders = args.Request.Headers;
   requestHeaders.SetHeader("Custom", "Value");
};

Переопределение ответа для его упреждающей замены

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

Последовательность переопределения ответов

Схема последовательности для переопределения ответов

  1. Ведущее приложение настраивает фильтр.WebResourceRequested
  2. Ведущее приложение определяет обработчики событий для WebResourceRequested и WebResourceResponseReceived.
  3. Ведущее приложение осуществляет переход по элементу управления WebView2 на веб-страницу.
  4. Элемент управления WebView2 создает запрос ресурса, необходимого для веб-страницы.
  5. Элемент управления WebView2 запускает WebResourceRequested событие для ведущего приложения.
  6. Ведущее приложение прослушивает и обрабатывает WebResourceRequested событие.
  7. Ведущее приложение задает ответ обработчику WebResourceRequested событий. Ведущее приложение также может отложить WebResourceRequested событие, что означает, что ведущее приложение запрашивает дополнительное время, чтобы решить, что делать.
  8. Элемент управления WebView2 отображает ответ как ресурс.

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

// Add a filter to select all image resources
webView.CoreWebView2.AddWebResourceRequestedFilter(
      "*", CoreWebView2WebResourceContext.Image);
webView.CoreWebView2.WebResourceRequested += delegate (
   object sender, CoreWebView2WebResourceRequestedEventArgs args) {
   
   // Replace the remote image resource with a local one specified at the path customImagePath.
   // If response is not set, the request will continue as it is.
   FileStream fs = File.Open(customImagePath, FileMode.Open);
   CoreWebView2WebResourceResponse response = webView.CoreWebView2.Environment.CreateWebResourceResponse(fs, 200, "OK", "Content-Type: image/jpeg");
   args.Response = response;
};

Создание пользовательского запроса и навигация с помощью этого запроса

Этот NavigateWithWebResourceRequest метод позволяет приложению-организатору перемещаться по элементу управления WebView2 с помощью пользовательского WebResourceRequestфайла . С помощью этого API можно создать запросы GET или POST с настраиваемыми заголовками и содержимым. Затем элемент управления WebView2 будет осуществлять навигацию с помощью этого пользовательского запроса.

Пример: создание пользовательского запроса и навигация с помощью этого запроса

// This code posts text input=Hello to the POST form page in W3Schools.

// Need to convert post data to UTF-8 as required by the application/x-www-form-urlencoded Content-Type
UTF8Encoding utfEncoding = new UTF8Encoding();
byte[] postData = utfEncoding.GetBytes("input=Hello");

MemoryStream postDataStream = new MemoryStream(postData.Length);
postDataStream.Write(postData, 0, postData.Length);
postDataStream.Seek(0, SeekOrigin.Begin);

// This acts as a HTML form submit to https://www.w3schools.com/action_page.php
CoreWebView2WebResourceRequest webResourceRequest =
environment.CreateWebResourceRequest("https://www.w3schools.com/action_page.php",
                                     "POST",
                                     postDataStream,
                                    "Content-Type: application/x-www-form-urlencoded");
webView.CoreWebView2.NavigateWithWebResourceRequest(webResourceRequest);

Мониторинг запросов и ответов с помощью события WebResourceResponseReceived

Вы можете отслеживать запросы и ответы с помощью WebResourceResponseReceived события, чтобы читать любое значение заголовка.

Пример: мониторинг запросов и ответов с помощью события WebResourceResponseReceived

В этом примере показано, как прочитать значение заголовка авторизации путем отслеживания запросов и откликов через WebResourceResponseReceived событие.

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

WebView.CoreWebView2.WebResourceResponseReceived += CoreWebView2_WebResourceResponseReceived;

// Note: modifications made to request are set but have no effect on WebView processing it.
private async void WebView_WebResourceResponseReceived(object sender, CoreWebView2WebResourceResponseReceivedEventArgs e)
{
    // Actual headers sent with request
    foreach (var current in e.Request.Headers)
    {
        Console.WriteLine(current);
    }

    // Headers in response received
    foreach (var current in e.Response.Headers)
    {
        Console.WriteLine(current);
    }

    // Status code from response received
    int status = e.Response.StatusCode;
    if (status == 200)
    {
        Console.WriteLine("Request succeeded!");

        // Get response body
        try
        {
            System.IO.Stream content = await e.Response.GetContentAsync();
            // Null will be returned if no content was found for the response.
            if (content != null)
            {
                DoSomethingWithResponseContent(content);
            }
        }
        catch (COMException ex)
        {
            // A COMException will be thrown if the content failed to load.
        }
    }
}

Обзор справочников по API

Запрос:

Отклик:

См. также