Chromium 中chrome.webRequest扩展接口定义c++

news2024/11/15 2:56:54

一、chrome.webRequest

注意 :从 Manifest V3 开始,"webRequestBlocking" 权限不再适用于大多数扩展程序。以 "declarativeNetRequest" 为例,它允许使用 declarativeNetRequest API。除了 "webRequestBlocking" 之外,webRequest API 保持不变,仍可正常使用。通过政策安装的扩展程序可以继续使用 "webRequestBlocking"

使用 chrome.webRequest API 可观察和分析流量,以及拦截、阻止或修改传输中的请求。

权限

webRequest

您必须在扩展程序清单中声明 "webRequest" 权限,才能使用 Web 请求 API 以及必要的主机权限。要拦截子资源请求, 扩展程序必须同时有权访问请求的网址及其发起者。例如:

{
  "name": "My extension",
  ...
  "permissions": [
    "webRequest"
  ],
  "host_permissions": [
    "*://*.google.com/*"
  ],
  ...
}

webRequestBlocking

必须填写此字段,才能注册屏蔽事件处理脚本。从 Manifest V3 开始, 适用于通过政策安装的扩展程序

webRequestAuthProvider

使用 onAuthRequired 方法的必需条件。请参阅 处理身份验证。

请求的生命周期

Web 请求 API 定义了一组遵循 Web 请求生命周期的事件。您可以使用 来观察和分析流量。某些同步事件允许您拦截、 屏蔽或修改请求

成功请求的事件生命周期如下所示,其后是事件定义:

从 webrequest API 的角度看网络请求的生命周期

更多参考 chrome.webRequest  |  API  |  Chrome for Developers 

二、chrome.webRequest c++接口定义:

1、web_request.json接口描述文件:

extensions\common\api\web_request.json

// Copyright 2012 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

[
  {
    "namespace": "webRequest",
    "description": "Use the <code>chrome.webRequest</code> API to observe and analyze traffic and to intercept, block, or modify requests in-flight.",
    "properties": {
      "MAX_HANDLER_BEHAVIOR_CHANGED_CALLS_PER_10_MINUTES": {
        "value": 20,
        "description": "The maximum number of times that <code>handlerBehaviorChanged</code> can be called per 10 minute sustained interval. <code>handlerBehaviorChanged</code> is an expensive function call that shouldn't be called often."
      }
    },
    "types": [
      {
        "id": "ResourceType",
        "type": "string",
        "enum": [
          {"name": "main_frame", "description": "Specifies the resource as the main frame."},
          {"name": "sub_frame", "description": "Specifies the resource as a sub frame."},
          {"name":  "stylesheet", "description": "Specifies the resource as a stylesheet."},
          {"name": "script", "description": "Specifies the resource as a script."},
          {"name": "image", "description": "Specifies the resource as an image."},
          {"name": "font", "description": "Specifies the resource as a font."},
          {"name": "object", "description": "Specifies the resource as an object."},
          {"name": "xmlhttprequest",
           "description": "Specifies the resource as an XMLHttpRequest."},
          {"name": "ping",
           "description": "Specifies the resource as a ping."},
          {"name": "csp_report",
          "description": "Specifies the resource as a Content Security Policy (CSP) report."},
          {"name": "media", "description": "Specifies the resource as a media object."},
          {"name": "websocket", "description": "Specifies the resource as a WebSocket."},
          {"name": "webbundle", "description": "Specifies the resource as a WebBundle."},
          {"name": "other", "description": "Specifies the resource as a type not included in the listed types."}
        ]
      },
      {
        "id": "OnBeforeRequestOptions",
        "type": "string",
        "enum": [
          {"name": "blocking", "description": "Specifies the request is blocked until the callback function returns."},
          {"name": "requestBody", "description": "Specifies that the request body should be included in the event."},
          {"name": "extraHeaders", "description": "Specifies that headers can violate Cross-Origin Resource Sharing (CORS)."}
        ]
      },
      {
        "id": "OnBeforeSendHeadersOptions",
        "type": "string",
        "enum": [
          {"name": "requestHeaders", "description": "Specifies that the request header should be included in the event."},
          {"name": "blocking", "description": "Specifies the request is blocked until the callback function returns."},
          {"name": "extraHeaders", "description": "Specifies that headers can violate Cross-Origin Resource Sharing (CORS)."}
        ]
      },
      {
        "id": "OnSendHeadersOptions",
        "type": "string",
        "enum": [
          {"name": "requestHeaders", "description": "Specifies that the request header should be included in the event."},
          {"name": "extraHeaders", "description": "Specifies that headers can violate Cross-Origin Resource Sharing (CORS)."}
        ]
      },
      {
        "id": "OnHeadersReceivedOptions",
        "type": "string",
        "enum": [
          {"name": "blocking", "description": "Specifies the request is blocked until the callback function returns."},
          {"name": "responseHeaders", "description": "Specifies that the response headers should be included in the event."},
          {"name": "extraHeaders", "description": "Specifies that headers can violate Cross-Origin Resource Sharing (CORS)."}
        ]
      },
      {
        "id": "OnAuthRequiredOptions",
        "type": "string",
        "enum": [
          {"name": "responseHeaders", "description": "Specifies that the response headers should be included in the event."},
          {"name": "blocking", "description": "Specifies the request is blocked until the callback function returns."},
          {"name": "asyncBlocking", "description": "Specifies that the callback function is handled asynchronously."},
          {"name": "extraHeaders", "description": "Specifies that headers can violate Cross-Origin Resource Sharing (CORS)."}
        ]
      },
      {
        "id": "OnResponseStartedOptions",
        "type": "string",
        "enum": [
          {"name": "responseHeaders", "description": "Specifies that the response headers should be included in the event."},
          {"name": "extraHeaders", "description": "Specifies that headers can violate Cross-Origin Resource Sharing (CORS)."}
        ]
      },
      {
        "id": "OnBeforeRedirectOptions",
        "type": "string",
        "enum": [
          {"name": "responseHeaders", "description": "Specifies that the response headers should be included in the event."},
          {"name": "extraHeaders", "description": "Specifies that headers can violate Cross-Origin Resource Sharing (CORS)."}
        ]
      },
      {
        "id": "OnCompletedOptions",
        "type": "string",
        "enum": [
          {"name": "responseHeaders", "description": "Specifies that the response headers should be included in the event."},
          {"name": "extraHeaders", "description": "Specifies that headers can violate Cross-Origin Resource Sharing (CORS)."}
        ]
      },
      {
        "id": "OnErrorOccurredOptions",
        "type": "string",
        "enum": [
          {"name": "extraHeaders", "description": "Specifies that headers can violate Cross-Origin Resource Sharing (CORS)."}
        ]
      },
      {
        "id": "RequestFilter",
        "type": "object",
        "description": "An object describing filters to apply to webRequest events.",
        "properties": {
          "urls": {
            "type": "array",
            "description": "A list of URLs or URL patterns. Requests that cannot match any of the URLs will be filtered out.",
            "items": { "type": "string" }
          },
          "types": {
            "type": "array",
            "optional": true,
            "description": "A list of request types. Requests that cannot match any of the types will be filtered out.",
            "items": { "$ref": "ResourceType" }
          },
          "tabId": { "type": "integer", "optional": true },
          "windowId": { "type": "integer", "optional": true }
        }
      },
      {
        "id": "HttpHeaders",
        "nocompile": true,
        "type": "array",
        "description": "An array of HTTP headers. Each header is represented as a dictionary containing the keys <code>name</code> and either <code>value</code> or <code>binaryValue</code>.",
        "items": {
          "type": "object",
          "properties": {
            "name": {"type": "string", "description": "Name of the HTTP header."},
            "value": {"type": "string", "optional": true, "description": "Value of the HTTP header if it can be represented by UTF-8."},
            "binaryValue": {
              "type": "array",
              "optional": true,
              "description": "Value of the HTTP header if it cannot be represented by UTF-8, stored as individual byte values (0..255).",
              "items": {"type": "integer"}
            }
          }
        }
      },
      {
        "id": "BlockingResponse",
        "nocompile": true,
        "type": "object",
        "description": "Returns value for event handlers that have the 'blocking' extraInfoSpec applied. Allows the event handler to modify network requests.",
        "properties": {
          "cancel": {
            "type": "boolean",
            "optional": true,
            "description": "If true, the request is cancelled. This prevents the request from being sent. This can be used as a response to the onBeforeRequest, onBeforeSendHeaders, onHeadersReceived and onAuthRequired events."
          },
          "redirectUrl": {
            "type": "string",
            "optional": true,
            "description": "Only used as a response to the onBeforeRequest and onHeadersReceived events. If set, the original request is prevented from being sent/completed and is instead redirected to the given URL. Redirections to non-HTTP schemes such as <code>data:</code> are allowed. Redirects initiated by a redirect action use the original request method for the redirect, with one exception: If the redirect is initiated at the onHeadersReceived stage, then the redirect will be issued using the GET method. Redirects from URLs with <code>ws://</code> and <code>wss://</code> schemes are <b>ignored</b>."
          },
          "requestHeaders": {
            "$ref": "HttpHeaders",
            "optional": true,
            "description": "Only used as a response to the onBeforeSendHeaders event. If set, the request is made with these request headers instead."
          },
          "responseHeaders": {
            "$ref": "HttpHeaders",
            "optional": true,
            "description": "Only used as a response to the onHeadersReceived event. If set, the server is assumed to have responded with these response headers instead. Only return <code>responseHeaders</code> if you really want to modify the headers in order to limit the number of conflicts (only one extension may modify <code>responseHeaders</code> for each request)."
          },
          "authCredentials": {
            "type": "object",
            "description": "Only used as a response to the onAuthRequired event. If set, the request is made using the supplied credentials.",
            "optional": true,
            "properties": {
              "username": {"type": "string"},
              "password": {"type": "string"}
            }
          }
        }
      },
      {
        "id": "UploadData",
        "type": "object",
        "properties": {
          "bytes": {
            "type": "any",
            "optional": true,
            "description": "An ArrayBuffer with a copy of the data."
          },
          "file": {
            "type": "string",
            "optional": true,
            "description": "A string with the file's path and name."
          }
        },
        "description": "Contains data uploaded in a URL request."
      },
      {
        "id": "FormDataItem",
        "choices": [
          { "type": "binary" },
          { "type": "string" }
        ],
        "description": "Contains data passed within form data. For urlencoded form it is stored as string if data is utf-8 string and as ArrayBuffer otherwise. For form-data it is ArrayBuffer. If form-data represents uploading file, it is string with filename, if the filename is provided."
      },
      {
        "id": "IgnoredActionType",
        "decription": "Denotes the extension proposed action which was ignored.",
        "type": "string",
        "enum": ["redirect", "request_headers", "response_headers", "auth_credentials"]
      }
    ],
    "functions": [
      {
        "name": "handlerBehaviorChanged",
        "type": "function",
        "description": "Needs to be called when the behavior of the webRequest handlers has changed to prevent incorrect handling due to caching. This function call is expensive. Don't call it often.",
        "parameters": [],
        "returns_async": {"name": "callback", "optional": true, "parameters": []}
      }
    ],
    "events": [
      {
        "name": "onBeforeRequest",
        "type": "function",
        "description": "Fired when a request is about to occur.",
        "parameters": [
          {
            "type": "object",
            "name": "details",
            "properties": {
              "requestId": {"type": "string", "description": "The ID of the request. Request IDs are unique within a browser session. As a result, they could be used to relate different events of the same request."},
              "url": {"type": "string"},
              "method": {"type": "string", "description": "Standard HTTP method."},
              "frameId": {"type": "integer", "description": "The value 0 indicates that the request happens in the main frame; a positive value indicates the ID of a subframe in which the request happens. If the document of a (sub-)frame is loaded (<code>type</code> is <code>main_frame</code> or <code>sub_frame</code>), <code>frameId</code> indicates the ID of this frame, not the ID of the outer frame. Frame IDs are unique within a tab."},
              "parentFrameId": {"type": "integer", "description": "ID of frame that wraps the frame which sent the request. Set to -1 if no parent frame exists."},
              "documentId": {"type": "string", "optional": true, "description": "The UUID of the document making the request."},
              "parentDocumentId": {"type": "string", "optional": true, "description": "The UUID of the parent document owning this frame. This is not set if there is no parent."},
              "documentLifecycle": {"$ref": "extensionTypes.DocumentLifecycle", "optional": true, "description": "The lifecycle the document is in."},
              "frameType": {"$ref": "extensionTypes.FrameType", "optional": true, "description": "The type of frame the request occurred in."},
              "requestBody": {
                "type": "object",
                "optional": true,
                "description": "Contains the HTTP request body data. Only provided if extraInfoSpec contains 'requestBody'.",
                "properties": {
                  "error": {"type": "string", "optional": true, "description": "Errors when obtaining request body data."},
                  "formData": {
                    "type": "object",
                    "optional": true,
                    "description": "If the request method is POST and the body is a sequence of key-value pairs encoded in UTF8, encoded as either multipart/form-data, or application/x-www-form-urlencoded, this dictionary is present and for each key contains the list of all values for that key. If the data is of another media type, or if it is malformed, the dictionary is not present. An example value of this dictionary is {'key': ['value1', 'value2']}.",
                    "properties": {},
                    "additionalProperties": {
                      "type": "array",
                      "items": { "$ref": "FormDataItem" }
                    }
                  },
                  "raw" : {
                    "type": "array",
                    "optional": true,
                    "items": {"$ref": "UploadData"},
                    "description": "If the request method is PUT or POST, and the body is not already parsed in formData, then the unparsed request body elements are contained in this array."
                  }
                }
              },
              "tabId": {"type": "integer", "description": "The ID of the tab in which the request takes place. Set to -1 if the request isn't related to a tab."},
              "type": {"$ref": "ResourceType", "description": "How the requested resource will be used."},
              "initiator": {"type": "string", "optional": true, "description": "The origin where the request was initiated. This does not change through redirects. If this is an opaque origin, the string 'null' will be used."},
              "timeStamp": {"type": "number", "description": "The time when this signal is triggered, in milliseconds since the epoch."}
            }
          }
        ],
        "extraParameters": [
          {
            "$ref": "RequestFilter",
            "name": "filter",
            "description": "A set of filters that restricts the events that will be sent to this listener."
          },
          {
            "type": "array",
            "optional": true,
            "name": "extraInfoSpec",
            "description": "Array of extra information that should be passed to the listener function.",
            "items": {
              "$ref": "OnBeforeRequestOptions"
            }
          }
        ],
        "returns": {
          "$ref": "BlockingResponse",
          "description": "If \"blocking\" is specified in the \"extraInfoSpec\" parameter, the event listener should return an object of this type.",
          "optional": true
        }
      },
      {
        "name": "onBeforeSendHeaders",
        "nocompile": true,
        "type": "function",
        "description": "Fired before sending an HTTP request, once the request headers are available. This may occur after a TCP connection is made to the server, but before any HTTP data is sent. ",
        "parameters": [
          {
            "type": "object",
            "name": "details",
            "properties": {
              "requestId": {"type": "string", "description": "The ID of the request. Request IDs are unique within a browser session. As a result, they could be used to relate different events of the same request."},
              "url": {"type": "string"},
              "method": {"type": "string", "description": "Standard HTTP method."},
              "frameId": {"type": "integer", "description": "The value 0 indicates that the request happens in the main frame; a positive value indicates the ID of a subframe in which the request happens. If the document of a (sub-)frame is loaded (<code>type</code> is <code>main_frame</code> or <code>sub_frame</code>), <code>frameId</code> indicates the ID of this frame, not the ID of the outer frame. Frame IDs are unique within a tab."},
              "parentFrameId": {"type": "integer", "description": "ID of frame that wraps the frame which sent the request. Set to -1 if no parent frame exists."},
              "documentId": {"type": "string", "description": "The UUID of the document making the request."},
              "parentDocumentId": {"type": "string", "optional": true, "description": "The UUID of the parent document owning this frame. This is not set if there is no parent."},
              "documentLifecycle": {"$ref": "extensionTypes.DocumentLifecycle", "description": "The lifecycle the document is in."},
              "frameType": {"$ref": "extensionTypes.FrameType", "description": "The type of frame the request occurred in."},
              "tabId": {"type": "integer", "description": "The ID of the tab in which the request takes place. Set to -1 if the request isn't related to a tab."},
              "initiator": {"type": "string", "optional": true, "description": "The origin where the request was initiated. This does not change through redirects. If this is an opaque origin, the string 'null' will be used."},
              "type": {"$ref": "ResourceType", "description": "How the requested resource will be used."},
              "timeStamp": {"type": "number", "description": "The time when this signal is triggered, in milliseconds since the epoch."},
              "requestHeaders": {"$ref": "HttpHeaders", "optional": true, "description": "The HTTP request headers that are going to be sent out with this request."}
            }
          }
        ],
        "extraParameters": [
          {
            "$ref": "RequestFilter",
            "name": "filter",
            "description": "A set of filters that restricts the events that will be sent to this listener."
          },
          {
            "type": "array",
            "optional": true,
            "name": "extraInfoSpec",
            "description": "Array of extra information that should be passed to the listener function.",
            "items": {
              "$ref": "OnBeforeSendHeadersOptions"
            }
          }
        ],
        "returns": {
          "$ref": "BlockingResponse",
          "description": "If \"blocking\" is specified in the \"extraInfoSpec\" parameter, the event listener should return an object of this type.",
          "optional": true
        }
      },
      {
        "name": "onSendHeaders",
        "nocompile": true,
        "type": "function",
        "description": "Fired just before a request is going to be sent to the server (modifications of previous onBeforeSendHeaders callbacks are visible by the time onSendHeaders is fired).",
        "parameters": [
          {
            "type": "object",
            "name": "details",
            "properties": {
              "requestId": {"type": "string", "description": "The ID of the request. Request IDs are unique within a browser session. As a result, they could be used to relate different events of the same request."},
              "url": {"type": "string"},
              "method": {"type": "string", "description": "Standard HTTP method."},
              "frameId": {"type": "integer", "description": "The value 0 indicates that the request happens in the main frame; a positive value indicates the ID of a subframe in which the request happens. If the document of a (sub-)frame is loaded (<code>type</code> is <code>main_frame</code> or <code>sub_frame</code>), <code>frameId</code> indicates the ID of this frame, not the ID of the outer frame. Frame IDs are unique within a tab."},
              "parentFrameId": {"type": "integer", "description": "ID of frame that wraps the frame which sent the request. Set to -1 if no parent frame exists."},
              "documentId": {"type": "string", "description": "The UUID of the document making the request."},
              "parentDocumentId": {"type": "string", "optional": true, "description": "The UUID of the parent document owning this frame. This is not set if there is no parent."},
              "documentLifecycle": {"$ref": "extensionTypes.DocumentLifecycle", "description": "The lifecycle the document is in."},
              "frameType": {"$ref": "extensionTypes.FrameType", "description": "The type of frame the request occurred in."},
              "tabId": {"type": "integer", "description": "The ID of the tab in which the request takes place. Set to -1 if the request isn't related to a tab."},
              "type": {"$ref": "ResourceType", "description": "How the requested resource will be used."},
              "initiator": {"type": "string", "optional": true, "description": "The origin where the request was initiated. This does not change through redirects. If this is an opaque origin, the string 'null' will be used."},
              "timeStamp": {"type": "number", "description": "The time when this signal is triggered, in milliseconds since the epoch."},
              "requestHeaders": {"$ref": "HttpHeaders", "optional": true, "description": "The HTTP request headers that have been sent out with this request."}
            }
          }
        ],
        "extraParameters": [
          {
            "$ref": "RequestFilter",
            "name": "filter",
            "description": "A set of filters that restricts the events that will be sent to this listener."
          },
          {
            "type": "array",
            "optional": true,
            "name": "extraInfoSpec",
            "description": "Array of extra information that should be passed to the listener function.",
            "items": {
              "$ref": "OnSendHeadersOptions"
            }
          }
        ]
      },
      {
        "name": "onHeadersReceived",
        "nocompile": true,
        "type": "function",
        "description": "Fired when HTTP response headers of a request have been received.",
        "parameters": [
          {
            "type": "object",
            "name": "details",
            "properties": {
              "requestId": {"type": "string", "description": "The ID of the request. Request IDs are unique within a browser session. As a result, they could be used to relate different events of the same request."},
              "url": {"type": "string"},
              "method": {"type": "string", "description": "Standard HTTP method."},
              "frameId": {"type": "integer", "description": "The value 0 indicates that the request happens in the main frame; a positive value indicates the ID of a subframe in which the request happens. If the document of a (sub-)frame is loaded (<code>type</code> is <code>main_frame</code> or <code>sub_frame</code>), <code>frameId</code> indicates the ID of this frame, not the ID of the outer frame. Frame IDs are unique within a tab."},
              "parentFrameId": {"type": "integer", "description": "ID of frame that wraps the frame which sent the request. Set to -1 if no parent frame exists."},
              "documentId": {"type": "string", "description": "The UUID of the document making the request."},
              "parentDocumentId": {"type": "string", "optional": true, "description": "The UUID of the parent document owning this frame. This is not set if there is no parent."},
              "documentLifecycle": {"$ref": "extensionTypes.DocumentLifecycle", "description": "The lifecycle the document is in."},
              "frameType": {"$ref": "extensionTypes.FrameType", "description": "The type of frame the request occurred in."},
              "tabId": {"type": "integer", "description": "The ID of the tab in which the request takes place. Set to -1 if the request isn't related to a tab."},
              "type": {"$ref": "ResourceType", "description": "How the requested resource will be used."},
              "initiator": {"type": "string", "optional": true, "description": "The origin where the request was initiated. This does not change through redirects. If this is an opaque origin, the string 'null' will be used."},
              "timeStamp": {"type": "number", "description": "The time when this signal is triggered, in milliseconds since the epoch."},
              "statusLine": {"type": "string", "description": "HTTP status line of the response or the 'HTTP/0.9 200 OK' string for HTTP/0.9 responses (i.e., responses that lack a status line)."},
              "responseHeaders": {"$ref": "HttpHeaders", "optional": true, "description": "The HTTP response headers that have been received with this response."},
              "statusCode": {"type": "integer", "description": "Standard HTTP status code returned by the server."}
             }
          }
        ],
        "extraParameters": [
          {
            "$ref": "RequestFilter",
            "name": "filter",
            "description": "A set of filters that restricts the events that will be sent to this listener."
          },
          {
            "type": "array",
            "optional": true,
            "name": "extraInfoSpec",
            "description": "Array of extra information that should be passed to the listener function.",
            "items": {
              "$ref": "OnHeadersReceivedOptions"
            }
          }
        ],
        "returns": {
          "$ref": "BlockingResponse",
          "description": "If \"blocking\" is specified in the \"extraInfoSpec\" parameter, the event listener should return an object of this type.",
          "optional": true
        }
      },
      {
        "name": "onAuthRequired",
        "nocompile": true,
        "type": "function",
        "description": "Fired when an authentication failure is received. The listener has three options: it can provide authentication credentials, it can cancel the request and display the error page, or it can take no action on the challenge. If bad user credentials are provided, this may be called multiple times for the same request. Note, only one of <code>'blocking'</code> or <code>'asyncBlocking'</code> modes must be specified in the <code>extraInfoSpec</code> parameter.",
        "parameters": [
          {
            "type": "object",
            "name": "details",
            "properties": {
              "requestId": {"type": "string", "description": "The ID of the request. Request IDs are unique within a browser session. As a result, they could be used to relate different events of the same request."},
              "url": {"type": "string"},
              "method": {"type": "string", "description": "Standard HTTP method."},
              "frameId": {"type": "integer", "description": "The value 0 indicates that the request happens in the main frame; a positive value indicates the ID of a subframe in which the request happens. If the document of a (sub-)frame is loaded (<code>type</code> is <code>main_frame</code> or <code>sub_frame</code>), <code>frameId</code> indicates the ID of this frame, not the ID of the outer frame. Frame IDs are unique within a tab."},
              "parentFrameId": {"type": "integer", "description": "ID of frame that wraps the frame which sent the request. Set to -1 if no parent frame exists."},
              "documentId": {"type": "string", "description": "The UUID of the document making the request."},
              "parentDocumentId": {"type": "string", "optional": true, "description": "The UUID of the parent document owning this frame. This is not set if there is no parent."},
              "documentLifecycle": {"$ref": "extensionTypes.DocumentLifecycle", "description": "The lifecycle the document is in."},
              "frameType": {"$ref": "extensionTypes.FrameType", "description": "The type of frame the request occurred in."},
              "tabId": {"type": "integer", "description": "The ID of the tab in which the request takes place. Set to -1 if the request isn't related to a tab."},
              "type": {"$ref": "ResourceType", "description": "How the requested resource will be used."},
              "initiator": {"type": "string", "optional": true, "description": "The origin where the request was initiated. This does not change through redirects. If this is an opaque origin, the string 'null' will be used."},
              "timeStamp": {"type": "number", "description": "The time when this signal is triggered, in milliseconds since the epoch."},
              "scheme": {"type": "string", "description": "The authentication scheme, e.g. Basic or Digest."},
              "realm": {"type": "string", "description": "The authentication realm provided by the server, if there is one.", "optional": true},
              "challenger": {"type": "object", "description": "The server requesting authentication.", "properties": {"host": {"type": "string"}, "port": {"type": "integer"}}},
              "isProxy": {"type": "boolean", "description": "True for Proxy-Authenticate, false for WWW-Authenticate."},
              "responseHeaders": {"$ref": "HttpHeaders", "optional": true, "description": "The HTTP response headers that were received along with this response."},
              "statusLine": {"type": "string", "description": "HTTP status line of the response or the 'HTTP/0.9 200 OK' string for HTTP/0.9 responses (i.e., responses that lack a status line) or an empty string if there are no headers."},
              "statusCode": {"type": "integer", "description": "Standard HTTP status code returned by the server."}
            }
          },
          {
            "type": "function",
            "optional": true,
            "description" : "Only valid if <code>'asyncBlocking'</code> is specified as one of the <code>OnAuthRequiredOptions</code>.",
            "name": "asyncCallback",
            "parameters": [
              {"name": "response", "$ref": "BlockingResponse"}
            ]
          }
        ],
        "extraParameters": [
          {
            "$ref": "RequestFilter",
            "name": "filter",
            "description": "A set of filters that restricts the events that will be sent to this listener."
          },
          {
            "type": "array",
            "optional": true,
            "name": "extraInfoSpec",
            "description": "Array of extra information that should be passed to the listener function.",
            "items": {
              "$ref": "OnAuthRequiredOptions"
            }
          }
        ],
        "returns": {
          "$ref": "BlockingResponse",
          "description": "If \"blocking\" is specified in the \"extraInfoSpec\" parameter, the event listener should return an object of this type.",
          "optional": true
        }
      },
      {
        "name": "onResponseStarted",
        "nocompile": true,
        "type": "function",
        "description": "Fired when the first byte of the response body is received. For HTTP requests, this means that the status line and response headers are available.",
        "parameters": [
          {
            "type": "object",
            "name": "details",
            "properties": {
              "requestId": {"type": "string", "description": "The ID of the request. Request IDs are unique within a browser session. As a result, they could be used to relate different events of the same request."},
              "url": {"type": "string"},
              "method": {"type": "string", "description": "Standard HTTP method."},
              "frameId": {"type": "integer", "description": "The value 0 indicates that the request happens in the main frame; a positive value indicates the ID of a subframe in which the request happens. If the document of a (sub-)frame is loaded (<code>type</code> is <code>main_frame</code> or <code>sub_frame</code>), <code>frameId</code> indicates the ID of this frame, not the ID of the outer frame. Frame IDs are unique within a tab."},
              "parentFrameId": {"type": "integer", "description": "ID of frame that wraps the frame which sent the request. Set to -1 if no parent frame exists."},
              "documentId": {"type": "string", "description": "The UUID of the document making the request."},
              "parentDocumentId": {"type": "string", "optional": true, "description": "The UUID of the parent document owning this frame. This is not set if there is no parent."},
              "documentLifecycle": {"$ref": "extensionTypes.DocumentLifecycle", "description": "The lifecycle the document is in."},
              "frameType": {"$ref": "extensionTypes.FrameType", "description": "The type of frame the request occurred in."},
              "tabId": {"type": "integer", "description": "The ID of the tab in which the request takes place. Set to -1 if the request isn't related to a tab."},
              "type": {"$ref": "ResourceType", "description": "How the requested resource will be used."},
              "initiator": {"type": "string", "optional": true, "description": "The origin where the request was initiated. This does not change through redirects. If this is an opaque origin, the string 'null' will be used."},
              "timeStamp": {"type": "number", "description": "The time when this signal is triggered, in milliseconds since the epoch."},
              "ip": {"type": "string", "optional": true, "description": "The server IP address that the request was actually sent to. Note that it may be a literal IPv6 address."},
              "fromCache": {"type": "boolean", "description": "Indicates if this response was fetched from disk cache."},
              "statusCode": {"type": "integer", "description": "Standard HTTP status code returned by the server."},
              "responseHeaders": {"$ref": "HttpHeaders", "optional": true, "description": "The HTTP response headers that were received along with this response."},
              "statusLine": {"type": "string", "description": "HTTP status line of the response or the 'HTTP/0.9 200 OK' string for HTTP/0.9 responses (i.e., responses that lack a status line) or an empty string if there are no headers."}
            }
          }
        ],
        "extraParameters": [
          {
            "$ref": "RequestFilter",
            "name": "filter",
            "description": "A set of filters that restricts the events that will be sent to this listener."
          },
          {
            "type": "array",
            "optional": true,
            "name": "extraInfoSpec",
            "description": "Array of extra information that should be passed to the listener function.",
            "items": {
              "$ref": "OnResponseStartedOptions"
            }
          }
        ]
      },
      {
        "name": "onBeforeRedirect",
        "type": "function",
        "nocompile": true,
        "description": "Fired when a server-initiated redirect is about to occur.",
        "parameters": [
          {
            "type": "object",
            "name": "details",
            "properties": {
              "requestId": {"type": "string", "description": "The ID of the request. Request IDs are unique within a browser session. As a result, they could be used to relate different events of the same request."},
              "url": {"type": "string"},
              "method": {"type": "string", "description": "Standard HTTP method."},
              "frameId": {"type": "integer", "description": "The value 0 indicates that the request happens in the main frame; a positive value indicates the ID of a subframe in which the request happens. If the document of a (sub-)frame is loaded (<code>type</code> is <code>main_frame</code> or <code>sub_frame</code>), <code>frameId</code> indicates the ID of this frame, not the ID of the outer frame. Frame IDs are unique within a tab."},
              "parentFrameId": {"type": "integer", "description": "ID of frame that wraps the frame which sent the request. Set to -1 if no parent frame exists."},
              "documentId": {"type": "string", "description": "The UUID of the document making the request."},
              "parentDocumentId": {"type": "string", "optional": true, "description": "The UUID of the parent document owning this frame. This is not set if there is no parent."},
              "documentLifecycle": {"$ref": "extensionTypes.DocumentLifecycle", "description": "The lifecycle the document is in."},
              "frameType": {"$ref": "extensionTypes.FrameType", "description": "The type of frame the request occurred in."},
              "tabId": {"type": "integer", "description": "The ID of the tab in which the request takes place. Set to -1 if the request isn't related to a tab."},
              "type": {"$ref": "ResourceType", "description": "How the requested resource will be used."},
              "initiator": {"type": "string", "optional": true, "description": "The origin where the request was initiated. This does not change through redirects. If this is an opaque origin, the string 'null' will be used."},
              "timeStamp": {"type": "number", "description": "The time when this signal is triggered, in milliseconds since the epoch."},
              "ip": {"type": "string", "optional": true, "description": "The server IP address that the request was actually sent to. Note that it may be a literal IPv6 address."},
              "fromCache": {"type": "boolean", "description": "Indicates if this response was fetched from disk cache."},
              "statusCode": {"type": "integer", "description": "Standard HTTP status code returned by the server."},
              "redirectUrl": {"type": "string", "description": "The new URL."},
              "responseHeaders": {"$ref": "HttpHeaders", "optional": true, "description": "The HTTP response headers that were received along with this redirect."},
              "statusLine": {"type": "string", "description": "HTTP status line of the response or the 'HTTP/0.9 200 OK' string for HTTP/0.9 responses (i.e., responses that lack a status line) or an empty string if there are no headers."}
            }
          }
        ],
        "extraParameters": [
          {
            "$ref": "RequestFilter",
            "name": "filter",
            "description": "A set of filters that restricts the events that will be sent to this listener."
          },
          {
            "type": "array",
            "optional": true,
            "name": "extraInfoSpec",
            "description": "Array of extra information that should be passed to the listener function.",
            "items": {
              "$ref": "OnBeforeRedirectOptions"
            }
          }
        ]
      },
      {
        "name": "onCompleted",
        "type": "function",
        "nocompile": true,
        "description": "Fired when a request is completed.",
        "parameters": [
          {
            "type": "object",
            "name": "details",
            "properties": {
              "requestId": {"type": "string", "description": "The ID of the request. Request IDs are unique within a browser session. As a result, they could be used to relate different events of the same request."},
              "url": {"type": "string"},
              "method": {"type": "string", "description": "Standard HTTP method."},
              "frameId": {"type": "integer", "description": "The value 0 indicates that the request happens in the main frame; a positive value indicates the ID of a subframe in which the request happens. If the document of a (sub-)frame is loaded (<code>type</code> is <code>main_frame</code> or <code>sub_frame</code>), <code>frameId</code> indicates the ID of this frame, not the ID of the outer frame. Frame IDs are unique within a tab."},
              "parentFrameId": {"type": "integer", "description": "ID of frame that wraps the frame which sent the request. Set to -1 if no parent frame exists."},
              "documentId": {"type": "string", "description": "The UUID of the document making the request."},
              "parentDocumentId": {"type": "string", "optional": true, "description": "The UUID of the parent document owning this frame. This is not set if there is no parent."},
              "documentLifecycle": {"$ref": "extensionTypes.DocumentLifecycle", "description": "The lifecycle the document is in."},
              "frameType": {"$ref": "extensionTypes.FrameType", "description": "The type of frame the request occurred in."},
              "tabId": {"type": "integer", "description": "The ID of the tab in which the request takes place. Set to -1 if the request isn't related to a tab."},
              "type": {"$ref": "ResourceType", "description": "How the requested resource will be used."},
              "initiator": {"type": "string", "optional": true, "description": "The origin where the request was initiated. This does not change through redirects. If this is an opaque origin, the string 'null' will be used."},
              "timeStamp": {"type": "number", "description": "The time when this signal is triggered, in milliseconds since the epoch."},
              "ip": {"type": "string", "optional": true, "description": "The server IP address that the request was actually sent to. Note that it may be a literal IPv6 address."},
              "fromCache": {"type": "boolean", "description": "Indicates if this response was fetched from disk cache."},
              "statusCode": {"type": "integer", "description": "Standard HTTP status code returned by the server."},
              "responseHeaders": {"$ref": "HttpHeaders", "optional": true, "description": "The HTTP response headers that were received along with this response."},
              "statusLine": {"type": "string", "description": "HTTP status line of the response or the 'HTTP/0.9 200 OK' string for HTTP/0.9 responses (i.e., responses that lack a status line) or an empty string if there are no headers."}
            }
          }
        ],
        "extraParameters": [
          {
            "$ref": "RequestFilter",
            "name": "filter",
            "description": "A set of filters that restricts the events that will be sent to this listener."
          },
          {
            "type": "array",
            "optional": true,
            "name": "extraInfoSpec",
            "description": "Array of extra information that should be passed to the listener function.",
            "items": {
              "$ref": "OnCompletedOptions"
            }
          }
        ]
      },
      {
        "name": "onErrorOccurred",
        "type": "function",
        "description": "Fired when an error occurs.",
        "parameters": [
          {
            "type": "object",
            "name": "details",
            "properties": {
              "requestId": {"type": "string", "description": "The ID of the request. Request IDs are unique within a browser session. As a result, they could be used to relate different events of the same request."},
              "url": {"type": "string"},
              "method": {"type": "string", "description": "Standard HTTP method."},
              "frameId": {"type": "integer", "description": "The value 0 indicates that the request happens in the main frame; a positive value indicates the ID of a subframe in which the request happens. If the document of a (sub-)frame is loaded (<code>type</code> is <code>main_frame</code> or <code>sub_frame</code>), <code>frameId</code> indicates the ID of this frame, not the ID of the outer frame. Frame IDs are unique within a tab."},
              "parentFrameId": {"type": "integer", "description": "ID of frame that wraps the frame which sent the request. Set to -1 if no parent frame exists."},
              "documentId": {"type": "string", "description": "The UUID of the document making the request. This value is not present if the request is a navigation of a frame."},
              "parentDocumentId": {"type": "string", "optional": true, "description": "The UUID of the parent document owning this frame. This is not set if there is no parent."},
              "documentLifecycle": {"$ref": "extensionTypes.DocumentLifecycle", "description": "The lifecycle the document is in."},
              "frameType": {"$ref": "extensionTypes.FrameType", "description": "The type of frame the request occurred in."},
              "tabId": {"type": "integer", "description": "The ID of the tab in which the request takes place. Set to -1 if the request isn't related to a tab."},
              "type": {"$ref": "ResourceType", "description": "How the requested resource will be used."},
              "initiator": {"type": "string", "optional": true, "description": "The origin where the request was initiated. This does not change through redirects. If this is an opaque origin, the string 'null' will be used."},
              "timeStamp": {"type": "number", "description": "The time when this signal is triggered, in milliseconds since the epoch."},
              "ip": {"type": "string", "optional": true, "description": "The server IP address that the request was actually sent to. Note that it may be a literal IPv6 address."},
              "fromCache": {"type": "boolean", "description": "Indicates if this response was fetched from disk cache."},
              "error": {"type": "string", "description": "The error description. This string is <em>not</em> guaranteed to remain backwards compatible between releases. You must not parse and act based upon its content."}
            }
          }
        ],
        "extraParameters": [
          {
            "$ref": "RequestFilter",
            "name": "filter",
            "description": "A set of filters that restricts the events that will be sent to this listener."
          },
          {
            "type": "array",
            "optional": true,
            "name": "extraInfoSpec",
            "description": "Array of extra information that should be passed to the listener function.",
            "items": {
              "$ref": "OnErrorOccurredOptions"
            }
          }
        ]
      },
      {
        "name": "onActionIgnored",
        "type": "function",
        "description": "Fired when an extension's proposed modification to a network request is ignored. This happens in case of conflicts with other extensions.",
        "parameters": [
          {
            "type": "object",
            "name": "details",
            "properties": {
              "requestId": {"type": "string", "description": "The ID of the request. Request IDs are unique within a browser session. As a result, they could be used to relate different events of the same request."},
              "action": {"$ref": "IgnoredActionType", "description": "The proposed action which was ignored."}
            }
          }
        ]
      }
    ]
  }
]

2、web_request.json生成的c++文件:

out\Debug\gen\extensions\common\api\web_request.h

out\Debug\gen\extensions\common\api\web_request.cc

3、web_request api接口定义c++:

extensions\browser\api\web_request\web_request_api.h

extensions\browser\api\web_request\web_request_api.cc

namespace extensions {

// Support class for the WebRequest API. Lives on the UI thread. Most of the
// work is done by ExtensionWebRequestEventRouter below. This class observes
// extensions::EventRouter to deal with event listeners. There is one instance
// per BrowserContext which is shared with incognito.
class WebRequestAPI : public BrowserContextKeyedAPI,
                      public EventRouter::Observer,
                      public ExtensionRegistryObserver {
 public:
  // A callback used to asynchronously respond to an intercepted authentication
  // request. If |should_cancel| is true the request will be cancelled.
  // Otherwise any supplied |credentials| will be used. If no credentials are
  // supplied, default browser behavior will follow (e.g. UI prompt for login).
  using AuthRequestCallback = base::OnceCallback<void(
      const std::optional<net::AuthCredentials>& credentials,
      bool should_cancel)>;

  // An interface which is held by ProxySet defined below.
  class Proxy {
   public:
    virtual ~Proxy() = default;

    // Asks the Proxy to handle an auth request on behalf of one of its known
    // in-progress network requests. If the request will *not* be handled by
    // the proxy, |callback| should be invoked with |std::nullopt|.
    virtual void HandleAuthRequest(
        const net::AuthChallengeInfo& auth_info,
        scoped_refptr<net::HttpResponseHeaders> response_headers,
        int32_t request_id,
        AuthRequestCallback callback);
  };

  // A ProxySet is a set of proxies used by WebRequestAPI: It holds Proxy
  // instances, and removes all proxies when it is destroyed.
  class ProxySet {
   public:
    ProxySet();

    ProxySet(const ProxySet&) = delete;
    ProxySet& operator=(const ProxySet&) = delete;

    ~ProxySet();

    // Add a Proxy.
    void AddProxy(std::unique_ptr<Proxy> proxy);
    // Remove a Proxy. The removed proxy is deleted upon this call.
    void RemoveProxy(Proxy* proxy);

    // Associates |proxy| with |id|. |proxy| must already be registered within
    // this ProxySet.
    //
    // Each Proxy may be responsible for multiple requests, but any given
    // request identified by |id| must be associated with only a single proxy.
    void AssociateProxyWithRequestId(Proxy* proxy,
                                     const content::GlobalRequestID& id);

    // Disassociates |proxy| with |id|. |proxy| must already be registered
    // within this ProxySet.
    void DisassociateProxyWithRequestId(Proxy* proxy,
                                        const content::GlobalRequestID& id);

    Proxy* GetProxyFromRequestId(const content::GlobalRequestID& id);

    void MaybeProxyAuthRequest(
        const net::AuthChallengeInfo& auth_info,
        scoped_refptr<net::HttpResponseHeaders> response_headers,
        const content::GlobalRequestID& request_id,
        AuthRequestCallback callback);

   private:
    // Although these members are initialized on the UI thread, we expect at
    // least one memory barrier before actually calling Generate in the IO
    // thread, so we don't protect them with a lock.
    std::set<std::unique_ptr<Proxy>, base::UniquePtrComparator> proxies_;

    // Bi-directional mapping between request ID and Proxy for faster lookup.
    std::map<content::GlobalRequestID, Proxy*> request_id_to_proxy_map_;
    std::map<Proxy*, std::set<content::GlobalRequestID>>
        proxy_to_request_id_map_;
  };

  class RequestIDGenerator {
   public:
    RequestIDGenerator();

    RequestIDGenerator(const RequestIDGenerator&) = delete;
    RequestIDGenerator& operator=(const RequestIDGenerator&) = delete;

    ~RequestIDGenerator();

    // Generates a WebRequest ID. If the same (routing_id,
    // network_service_request_id) pair is passed to this as was previously
    // passed to SaveID(), the |request_id| passed to SaveID() will be returned.
    int64_t Generate(int32_t routing_id, int32_t network_service_request_id);

    // This saves a WebRequest ID mapped to the (routing_id,
    // network_service_request_id) pair. Clients must call Generate() with the
    // same ID pair to retrieve the |request_id|, or else there may be a memory
    // leak.
    void SaveID(int32_t routing_id,
                int32_t network_service_request_id,
                uint64_t request_id);

   private:
    int64_t id_ = 0;
    std::map<std::pair<int32_t, int32_t>, uint64_t> saved_id_map_;
  };

  explicit WebRequestAPI(content::BrowserContext* context);

  WebRequestAPI(const WebRequestAPI&) = delete;
  WebRequestAPI& operator=(const WebRequestAPI&) = delete;

  ~WebRequestAPI() override;

  // BrowserContextKeyedAPI support:
  static BrowserContextKeyedAPIFactory<WebRequestAPI>* GetFactoryInstance();
  void Shutdown() override;

  // EventRouter::Observer overrides:
  void OnListenerRemoved(const EventListenerInfo& details) override;

  // If any WebRequest event listeners are currently active for this
  // BrowserContext, |*factory_request| is swapped out for a new request which
  // proxies through an internal URLLoaderFactory. This supports lifetime
  // observation and control on behalf of the WebRequest API.
  // |frame| and |render_process_id| are the frame and render process id in
  // which the URLLoaderFactory will be used. |frame| can be nullptr for
  // factories proxied for service worker.
  //
  // |navigation_response_task_runner| is a task runner that may be non-null for
  // navigation requests and can be used to run navigation request blocking
  // tasks.
  //
  // Returns |true| if the URLLoaderFactory will be proxied; |false| otherwise.
  bool MaybeProxyURLLoaderFactory(
      content::BrowserContext* browser_context,
      content::RenderFrameHost* frame,
      int render_process_id,
      content::ContentBrowserClient::URLLoaderFactoryType type,
      std::optional<int64_t> navigation_id,
      ukm::SourceIdObj ukm_source_id,
      mojo::PendingReceiver<network::mojom::URLLoaderFactory>* factory_receiver,
      mojo::PendingRemote<network::mojom::TrustedURLLoaderHeaderClient>*
          header_client,
      scoped_refptr<base::SequencedTaskRunner> navigation_response_task_runner,
      const url::Origin& request_initiator = url::Origin());

  // Any request which requires authentication to complete will be bounced
  // through this method.
  //
  // If this returns |true|, |callback| will eventually be invoked on the UI
  // thread.
  bool MaybeProxyAuthRequest(
      content::BrowserContext* browser_context,
      const net::AuthChallengeInfo& auth_info,
      scoped_refptr<net::HttpResponseHeaders> response_headers,
      const content::GlobalRequestID& request_id,
      bool is_main_frame,
      AuthRequestCallback callback,
      WebViewGuest* web_view_guest);

  // Starts proxying the connection with |factory|. This function can be called
  // only when MayHaveProxies() returns true.
  void ProxyWebSocket(
      content::RenderFrameHost* frame,
      content::ContentBrowserClient::WebSocketFactory factory,
      const GURL& url,
      const net::SiteForCookies& site_for_cookies,
      const std::optional<std::string>& user_agent,
      mojo::PendingRemote<network::mojom::WebSocketHandshakeClient>
          handshake_client);

  // Starts proxying WebTransport handshake.
  void ProxyWebTransport(
      content::RenderProcessHost& render_process_host,
      int frame_routing_id,
      const GURL& url,
      const url::Origin& initiator_origin,
      mojo::PendingRemote<network::mojom::WebTransportHandshakeClient>
          handshake_client,
      content::ContentBrowserClient::WillCreateWebTransportCallback callback);

  void ForceProxyForTesting();

  // Indicates whether or not the WebRequestAPI may have one or more proxies
  // installed to support the API.
  bool MayHaveProxies() const;

  // Indicates whether or not WebRequestAPI may have one or more proxies
  // installed to support intercepting websocket connections for extension
  // telemetry.
  // TODO(psarouthakis): This is here for the current implementation, but
  // will be refactored to live somewhere else so that we don't have to
  // create a full proxy just for telemetry.
  bool MayHaveWebsocketProxiesForExtensionTelemetry() const;

  // Indicates whether the WebRequestAPI is available to a RenderFrameHost
  // that embeds a WebView instance.
  bool IsAvailableToWebViewEmbedderFrame(
      content::RenderFrameHost* render_frame_host) const;

  bool HasExtraHeadersListenerForTesting();

 private:
  friend class BrowserContextKeyedAPIFactory<WebRequestAPI>;

  // BrowserContextKeyedAPI support:
  static const char* service_name() { return "WebRequestAPI"; }
  static const bool kServiceRedirectedInIncognito = true;
  static const bool kServiceIsNULLWhileTesting = true;

  // Checks if |MayHaveProxies()| has changed from false to true, and resets
  // URLLoaderFactories if so.
  void UpdateMayHaveProxies();

  // ExtensionRegistryObserver implementation.
  void OnExtensionLoaded(content::BrowserContext* browser_context,
                         const Extension* extension) override;
  void OnExtensionUnloaded(content::BrowserContext* browser_context,
                           const Extension* extension,
                           UnloadedExtensionReason reason) override;

  // This a proxy API for the tasks that are posted. It is either called
  // when the task is run and forwards to the corresponding member function
  // in ExtensionWebRequestEventRouter, or not, if the owning BrowserContext
  // goes away or the WeakPtr instance bound in the callback is invalidated.
  void UpdateActiveListener(
      content::BrowserContext* browser_context,
      WebRequestEventRouter::ListenerUpdateType update_type,
      const ExtensionId& extension_id,
      const std::string& sub_event_name,
      int worker_thread_id,
      int64_t service_worker_version_id);

  // This a proxy API for the tasks that are posted. It is either called
  // when the task is run and forwards to the corresponding member function
  // in ExtensionWebRequestEventRouter, or not, if the owning BrowserContext
  // goes away or the WeakPtr instance bound in the callback is invalidated.
  void RemoveLazyListener(content::BrowserContext* browser_context,
                          const ExtensionId& extension_id,
                          const std::string& sub_event_name);

  // A count of active extensions for this BrowserContext that use web request
  // permissions.
  int web_request_extension_count_ = 0;

  const raw_ptr<content::BrowserContext, DanglingUntriaged> browser_context_;

  RequestIDGenerator request_id_generator_;
  std::unique_ptr<ProxySet> proxies_;

  // Stores the last result of |MayHaveProxies()|, so it can be used in
  // |UpdateMayHaveProxies()|.
  bool may_have_proxies_;

  base::WeakPtrFactory<WebRequestAPI> weak_factory_{this};
};

class WebRequestInternalFunction : public ExtensionFunction {
 public:
  WebRequestInternalFunction() = default;

 protected:
  ~WebRequestInternalFunction() override = default;

  const std::string& extension_id_safe() const {
    return extension() ? extension_id() : base::EmptyString();
  }
};

class WebRequestInternalAddEventListenerFunction
    : public WebRequestInternalFunction {
 public:
  DECLARE_EXTENSION_FUNCTION("webRequestInternal.addEventListener",
                             WEBREQUESTINTERNAL_ADDEVENTLISTENER)

 protected:
  ~WebRequestInternalAddEventListenerFunction() override = default;

  // ExtensionFunction:
  ResponseAction Run() override;
};

class WebRequestInternalEventHandledFunction
    : public WebRequestInternalFunction {
 public:
  DECLARE_EXTENSION_FUNCTION("webRequestInternal.eventHandled",
                             WEBREQUESTINTERNAL_EVENTHANDLED)

 protected:
  ~WebRequestInternalEventHandledFunction() override = default;

 private:
  // Unblocks the network request. Use this function when handling incorrect
  // requests from the extension that cannot be detected by the schema
  // validator.
  void OnError(const std::string& event_name,
               const std::string& sub_event_name,
               uint64_t request_id,
               int render_process_id,
               int web_view_instance_id,
               std::unique_ptr<WebRequestEventRouter::EventResponse> response);

  // ExtensionFunction:
  ResponseAction Run() override;
};

class WebRequestHandlerBehaviorChangedFunction
    : public WebRequestInternalFunction {
 public:
  DECLARE_EXTENSION_FUNCTION("webRequest.handlerBehaviorChanged",
                             WEBREQUEST_HANDLERBEHAVIORCHANGED)

 protected:
  ~WebRequestHandlerBehaviorChangedFunction() override = default;

  // ExtensionFunction:
  void GetQuotaLimitHeuristics(
      extensions::QuotaLimitHeuristics* heuristics) const override;
  // Handle quota exceeded gracefully: Only warn the user but still execute the
  // function.
  void OnQuotaExceeded(std::string error) override;
  ResponseAction Run() override;
};

}  // namespace extensions

总结:

WebRequest API 接口c++定义介绍完毕,需要调试修改逻辑的可以在以上文件处更改。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2240555.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【MySQL】数据库必备知识:全面整合表的约束与深度解析

前言&#xff1a;本节内容讲述表的约束的相关内容。 表的约束博主将会通过两篇文章进行讲解&#xff0c; 这是第一篇上半部分。 讲到了约束概念。 以及几种常见约束。下面友友们开始学习吧&#xff01; ps:友友们使用了mysql就可以放心观看喽&#xff01; 目录 表的约束概念 …

堆排序,学习笔记

目录 一、概念 二、堆排序的基本思路 三、堆排序的基本步骤 1. 构建初始堆&#xff1a; 2. 排序过程 四、示例 五、应用场景 1. 优先级队列相关场景 2. TopK 值问题 一、概念 堆排序是一种基于二叉堆数据结构的排序算法。二叉堆是一种完全二叉树&#xff0c;它分为两种…

分享 pdf 转 word 的免费平台

背景 找了很多 pdf 转 word 的平台都骗进去要会员&#xff0c;终于找到一个真正免费的&#xff0c;遂分享。 网址 PDF转Word转换器 - 100%免费市面上最优质的PDF转Word转换器 - 免费且易于使用。无附加水印 - 快速将PDF转成Word。https://smallpdf.com/cn/pdf-to-word

llama-cpp模型轻量化部署与量化

一、定义 定义配置环境遇到的问题&#xff0c;交互模式下模型一直输出&#xff0c;不会停止模型量化Qwen1.5-7B 案例demo 二、实现 定义 主要应用与cpu 上的部署框架。由c完成。配置环境 https://github.com/ggerganov/llama.cpp https://github.com/echonoshy/cgft-llm/blo…

2024最新版JavaScript逆向爬虫教程-------基础篇之Proxy与Reflect详解

目录 一、监听对象的操作二、Proxy基本使用2.1 创建空代理2.2 定义捕获器2.2.1 Proxy的set和get捕获器2.2.2 Proxy(handler)的13个捕获器 三、Reflect的作用3.1 Reflect的使用3.2 Reflect其余方法(9个)3.3 Proxy与Reflect中的receiver参数3.4 Reflect中的construct方法 ECMAScr…

Ceph层次架构分析

Ceph的层次结构可以从逻辑上自下向上分为以下几个层次&#xff1a; 一、基础存储系统RADOS层 功能&#xff1a;RADOS&#xff08;Reliable Autonomic Distributed Object Store&#xff09;是Ceph的底层存储系统&#xff0c;提供了分布式存储的核心功能。它是一个完整的对象存…

webpack指南

​&#x1f308;个人主页&#xff1a;前端青山 &#x1f525;系列专栏&#xff1a;webpack篇 &#x1f516;人终将被年少不可得之物困其一生 依旧青山,本期给大家带来webpack篇专栏内容:webpack-指南 概念 中文&#xff1a; webpack | webpack中文文档 | webpack中文网 英文&…

网站架构知识之nginx第三天(day026 )

1.状态模块 使用方法&#xff1a;location /status/{ stub_$status; } 任意一个虚拟主机添加这个&#xff0c;就可以查看nginx状态。 对应指标及其说明

新的恶意软件活动通过游戏应用程序瞄准 Windows 用户

一种新的恶意软件 Winos4.0 被积极用于网络攻击活动。FortiGuard实验室发现&#xff0c;这种先进的恶意框架是从臭名昭著的 Gh0strat 演变而来的&#xff0c;配备了模块化组件&#xff0c;可在受感染的设备上进行一系列恶意活动。 这些攻击已在游戏相关应用程序中发现&#xf…

Redis - 集群(Cluster)

一、基本概念 上述的哨兵模式,提⾼了系统的可⽤性.但是真正⽤来存储数据的还是master和slave节点.所有的数 据都需要存储在单个master和slave节点中. 如果数据量很⼤,接近超出了master/slave所在机器的物理内存,就可能出现严重问题了. 如何获取更⼤的空间?加机器即可!所谓&q…

WebRTC项目一对一视频

开发步骤 1.客户端显示界面 2.打开摄像头并显示到页面 3.websocket连接 4.join、new-peer、resp-join信令实现 5.leave、peer-leave信令实现 6.offer、answer、candidate信令实现 7.综合调试和完善 1.客户端显示界面 步骤&#xff1a;创建html页面 主要是input、button、vide…

启动本地开发环境(自带热启动)yarn serve

文章目录 1. 安装 Yarn使用 npm 安装 Yarn使用 Chocolatey 安装 Yarn&#xff08;Windows 用户&#xff09;使用 Homebrew 安装 Yarn&#xff08;macOS 用户&#xff09; 2. 安装项目依赖3. 启动项目开发模式启动生产模式启动 4. 构建项目开发模式构建生产模式构建 5. 其他常用…

SpringCloud框架学习(第二部分:Consul、LoadBalancer和openFeign)

目录 六、Consul服务注册和发现 1.基本介绍 2.下载运行 3.服务注册与发现 &#xff08;1&#xff09;支付服务provider8001注册进consul &#xff08;2&#xff09;修改订单服务cloud-consumer-order80 4.CAP &#xff08;1&#xff09;CAP理论 &#xff08;2&#x…

SAP ABAP开发学习记录——报表选择界面初始值

程序中定义选择界面的部分只是创建输入框&#xff0c;在后续使用中需要自行添加搜索条件&#xff0c;而有关时间或者日期这种&#xff0c;希望自动创建一个默认值&#xff0c;有两种方法&#xff0c;一种是在选择界面初始化时增加语句另外一种是通过在选择界面创建变式实现。 …

16.UE5拉怪机制,怪物攻击玩家,伤害源,修复原视频中的BUG

2-18 拉怪机制&#xff0c;怪物攻击玩家、伤害源、黑板_哔哩哔哩_bilibili 目录 1.实行行为树实现拉怪机制 1.1行为树黑板 1.2获取施加伤害对象&#xff08;伤害源&#xff09; 2.修复原视频中&#xff0c;第二次攻击怪物后&#xff0c;怪物卡在原地不动的BUG 3.怪物攻击玩…

大数据新视界 -- 大数据大厂之 Impala 性能飞跃:动态分区调整的策略与方法(上)(21 / 30)

&#x1f496;&#x1f496;&#x1f496;亲爱的朋友们&#xff0c;热烈欢迎你们来到 青云交的博客&#xff01;能与你们在此邂逅&#xff0c;我满心欢喜&#xff0c;深感无比荣幸。在这个瞬息万变的时代&#xff0c;我们每个人都在苦苦追寻一处能让心灵安然栖息的港湾。而 我的…

Vue3 笔记 (万字速通)

此笔记来至于尚硅谷&#xff0c;仅供笔者复习使用 1. Vue3 简介 2020年9月18日&#xff0c;Vue.js发布版3.0版本&#xff0c;代号&#xff1a;One Piece&#xff08;n&#xff09; 经历了&#xff1a;4800次提交、40个RFC、600次PR、300贡献者 官方发版地址&#xff1a;Rele…

Linux基础1

Linux基础1 Linux基础1学习笔记 ‍ 声明&#xff01; ​​​学习视频来自B站up主 泷羽sec 有兴趣的师傅可以关注一下&#xff0c;如涉及侵权马上删除文章 笔记只是方便各位师傅的学习和探讨&#xff0c;文章所提到的网站以及内容&#xff0c;只做学习交流&#xff0c;其他…

Linux中.NET读取excel组件,不会出现The type initializer for ‘Gdip‘ threw an exception异常

组件&#xff0c;可通过nuget安装&#xff0c;直接搜名字&#xff1a; ExcelDataReader using ConsoleAppReadFileData.Model; using ExcelDataReader; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Task…

320页PDF | 集团IT蓝图总体规划报告-德勤(限免下载)

一、前言 这份报告是集团IT蓝图总体规划报告-德勤。在报告中详细阐述了德勤为某集团制定的全面IT蓝图总体规划&#xff0c;包括了集团信息化目标蓝图、IT应用规划、数据规划、IT集成架构、IT基础设施规划以及IT治理体系规划等关键领域&#xff0c;旨在为集团未来的信息化发展提…