Поделиться через


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

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

В этой статье описывается, как изменить сетевые запросы. Используйте этот API и выполните следующие действия:

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

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

Термин Определение
Перехватить Ведущее приложение может перехватить запрос, отправляемый из элемента управления 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

Запрос:

Ответ:

См. также