自訂網路要求管理

Microsoft Edge WebView2 控制項可讓您與網路要求互動及修改。 您可以使用 WebResourceRequestedWebResourceResponseReceived 事件來提供回應或修改網路要求。 另外還有特殊功能可讓您使用 NavigateWithWebResourceRequest API 來巡覽特定的網路要求。

本文說明如何修改網路要求。 使用此 API 和方法來:

  • 將本機檔案內容上傳至您的應用程式,以新增離線功能的支援。
  • 封鎖網頁中的內容,例如特定影像。
  • 微調特定頁面的驗證。

術語:

術語 定義
攔截 您的主應用程式可以攔截從 WebView2 控制項傳送至 HTTP 伺服器的要求、讀取或修改要求,然後將未變更或修改的要求傳送至 HTTP 伺服器 (或本機程式碼,而不是 HTTP 伺服器) 。
覆蓋 您的主應用程式可以覆寫從 HTTP 伺服器傳送至 WebView2 控制項的回應,並將自訂回應傳送至 WebView2 控制項,而不是原始回應。

使用自訂方法與基本方法的時機

事件 WebResourceRequested 是低階 API,可提供更多控制,但需要更多程式碼撰寫,而且使用起來很複雜。 針對一些常見的案例,我們提供更容易使用的 API,並針對這些特定案例優化,建議您使用這些 API,而不是本文中討論的 API。

與其使用 WebResourceRequested API,最好在可行時使用這些其他方法:

注意: 對於具有虛擬主機名稱的 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 (敏感性資訊) 、修改使用者代理程式等等。 回應標頭可用來提供回應的更多內容。

根據 URL 和資源類型篩選 WebResourceRequested 事件

若要接收 WebResourceRequested 事件,請根據 URL 和資源類型,指定主應用程式感興趣要求的篩選準則。

例如,假設主應用程式嘗試取代映射。 在此情況下,主應用程式只對影像的事件感興趣 WebResourceRequested 。 主應用程式只會藉由指定 resourceContext 影像的篩選來取得影像的事件。

另一個範例是主應用程式只對網站下的所有要求感興趣,例如 https://example.com 。 然後,應用程式可以將 URL 篩選指定為 https://example.com/* ,以取得與該網站相關聯的事件。

如需 URL 篩選器運作方式的詳細資訊,請參閱 CoreWebView2.AddWebResourceRequestedFilter 方法 > 備註

為何要攔截從 WebView2 傳送的要求?

攔截從 WebView2 傳送的要求可讓您進一步設定要求。 主應用程式可能想要在 WebView2 控制項本身不知道的要求中提供選擇性內容。 某些案例包括:

  • 您正在登入頁面,且應用程式具有認證,因此應用程式可以提供驗證標頭,而不需要使用者輸入這些認證。
  • 您想要在應用程式中使用離線功能,以便在未偵測到網際網路連線時,將 URL 重新導向至本機檔案路徑。
  • 您想要透過 POST 要求將本機檔案內容上傳至要求伺服器。

修改要求的順序

修改要求的順序圖

  1. 主應用程式會設定 WebResourceRequested 篩選準則。
  2. 主應用程式會定義 和 WebResourceResponseReceived 的事件處理常式 WebResourceRequested
  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. 主應用程式會定義 和 WebResourceResponseReceived 的事件處理常式 WebResourceRequested
  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 可讓您的主應用程式使用自訂 WebResourceRequest 流覽 WebView2 控制項。 您可以使用此 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 參考概觀

請求:

回應:

另請參閱