Custom management of network requests

The Microsoft Edge WebView2 control lets you interact with and modify network requests. You can either provide a response or modify the network request using the WebResourceRequested and WebResourceResponseReceived events. There is also special functionality that allows you to navigate with specific network requests using the NavigateWithWebResourceRequest API.

This article describes how you can modify network requests. Use this API and approach to:

  • Upload local file content to your app to add support for offline functionality.
  • Block content in a webpage, such as specific images.
  • Fine-tune authentication for specific pages.

Terminology:

Term Definition
intercept Your host app can intercept a request that is sent from the WebView2 control to the HTTP server, read or modify the request, and then send the unchanged or modified request to the HTTP server (or to local code instead of the HTTP server).
override Your host app can override a response that's sent from the HTTP server to the WebView2 control, and send a custom response to the WebView2 control instead of the original response.

When to use custom vs. basic approaches

The WebResourceRequested event is a low-level API that gives more control, but requires more coding and is complicated to use. For some common scenarios, we provide APIs that are easier to use and are optimized for those specific scenarios, and we recommend you use those APIs rather than the APIs discussed in this article.

Instead of using the WebResourceRequested APIs, it's preferable to use these other approaches when feasible:

Note: For URLs with virtual hostnames, using the WebResourceRequested event isn't supported. This is because the WebResourceRequested event isn't fired for the SetVirtualHostNameToFolderMapping method.

How your host app, the WebView2 control, and the HTTP server interact

The WebView2 control sits in between your host app and the HTTP server. When your host app navigates to a URI, the WebView2 control sends a request to the HTTP server. The HTTP server then sends a response to the WebView2 control.

Intercepting a request, to monitor or modify it

Your host app can intercept a request that is sent from the WebView2 control to the HTTP server, read or modify the request, and then send the unchanged or modified request to the HTTP server (or to local code instead of the HTTP server).

Intercepting the request allows you to customize the header content, URL, or the GET/POST method. The host app may want to intercept a request to provide optional POST content as part of the request.

The host app can change the properties of a request by using this API:

What you can do with headers

A HTTP header provides important information and metadata about a request or response. Changing headers enables you to perform powerful actions on the network.

A request header can be used to indicate the format of the response (such as the Accept-* headers), set authentication tokens, read and write cookies (sensitive information), modify the user agent, and so on. A response header can be used to provide more context of the response.

Filtering the WebResourceRequested event based on URL and resource type

In order to receive WebResourceRequested events, specify filters for the requests that the host app is interested in, based on URL and resource type.

For example, suppose the host app is trying to replace images. In this case, the host app is only interested in WebResourceRequested events for images. The host app would only get events for images by specifying the resourceContext filter for images.

Another example is if the host app is only interested in all requests that are under a site like https://example.com. Then the app can specify a URL filter as https://example.com/* to get events that are associated with that site.

For details about how the URL filter works, see CoreWebView2.AddWebResourceRequestedFilter Method > Remarks

Why would you want to intercept requests that are sent from WebView2?

Intercepting requests sent from WebView2 enables you to further configure your request. The host app might want to provide optional content as part of the request that the WebView2 control won't know on its own. Some scenarios include:

  • You're logging into a page and the app has credentials so the app can provide authentication header without the user having to enter those credentials.
  • You want offline functionality in the app so you redirect the URL to a local file path when no internet connection is detected.
  • You want to upload local file content to the request server via a POST request.

Sequence for modifying requests

Diagram of sequence for modifying requests

  1. The host app sets up a WebResourceRequested filter.
  2. The host app defines the event handlers for WebResourceRequested and WebResourceResponseReceived.
  3. The host app navigates the WebView2 control to a webpage.
  4. The WebView2 control creates a request for a resource that's needed for the webpage.
  5. The WebView2 control fires a WebResourceRequested event to the host app.
  6. The host app listens for and handles the WebResourceRequested event.
  7. The host app can modify headers at this point. The host app can also defer the WebResourceRequested event, which means that the host app asks for more time to decide what to do.
  8. The WebView2 network stack can add more headers (for example, can add cookies and authorization headers).
  9. The WebView2 control sends the request to the HTTP server.
  10. The HTTP server sends the response to the WebView2 control.
  11. The WebView2 control fires the WebResourceResponseReceived event.
  12. The host app listens for the WebResourceResponseReceived event and handles it.

Example: Intercepting a request, to monitor or modify it

In the following example, the host app intercepts the document request that is sent from the WebView2 control to the http://www.example.com HTTP server, adds a custom header value and sends the request.

// 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");
};

Overriding a response, to proactively replace it

By default, the HTTP server sends responses to the WebView2 control. Your host app can override a response that's sent from the HTTP server to the WebView2 control, and send a custom response to the WebView2 control instead of the original response.

Sequence for overriding responses

Diagram of sequence for overriding responses

  1. The host app sets up a WebResourceRequested filter.
  2. The host app defines the event handlers for WebResourceRequested and WebResourceResponseReceived.
  3. The host app navigates the WebView2 control to a webpage.
  4. The WebView2 control creates a request for a resource that's needed for the webpage.
  5. The WebView2 control fires a WebResourceRequested event to the host app.
  6. The host app listens for and handles the WebResourceRequested event.
  7. The host app sets a response to the WebResourceRequested event handler. The host app can also defer the WebResourceRequested event, which means that the host app asks for more time to decide what to do.
  8. The WebView2 control renders the response as the resource.

Example: Overriding a response, to proactively replace it

// 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;
};

Constructing a custom request and navigating using that request

The NavigateWithWebResourceRequest method allows your host app to navigate the WebView2 control using a custom WebResourceRequest. You can use this API to create a GET or POST request that has custom headers and content. Then the WebView2 control will navigate by using this custom request.

Example: Constructing a custom request and navigating using that request

// 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);

Monitoring the requests and responses via the WebResourceResponseReceived event

You can monitor the requests and responses via the WebResourceResponseReceived event, to read any header value.

Example: Monitoring the requests and responses via the WebResourceResponseReceived event

This example shows how to read the authorization header value by monitoring the requests and responses via the WebResourceResponseReceived event.

The following code demonstrates how the WebResourceResponseReceived event can be used.

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 Reference overview

Request:

Response:

See also