webRequest.onBeforeRequest

当要发出请求且在标头可用之前,会触发此事件。如果你想要取消或重定向请求,这是监听的好地方。

要取消或重定向请求,首先在 extraInfoSpec 数组参数中包含 "blocking"addListener() 中。然后,在监听器函数中,返回一个 BlockingResponse 对象,设置相应的属性

  • 要取消请求,请包含一个值为 truecancel 属性。
  • 要重定向请求,请包含一个名为 redirectUrl 的属性,其值为要重定向到的 URL。

如果扩展要将公共(例如 HTTPS)URL 重定向到 扩展页面,则扩展的 manifest.json 文件必须包含一个 web_accessible_resources 键,该键列出扩展页面的 URL。

当多个阻塞处理程序修改请求时,只有一组修改生效。重定向和取消具有相同的优先级。因此,如果你取消了一个请求,如果你另一个阻塞处理程序重定向该请求,你可能会再次看到具有相同 requestId 的另一个请求。

从 Firefox 52 开始,监听器可以返回一个 Promise,该 Promise 使用 BlockingResponse 解析,而不是返回 BlockingResponse。这使监听器能够异步处理请求。

如果你使用 "blocking",则你的 manifest.json 中必须具有 "webRequestBlocking" API 权限

语法

js
browser.webRequest.onBeforeRequest.addListener(
  listener,             // function
  filter,               //  object
  extraInfoSpec         //  optional array of strings
)
browser.webRequest.onBeforeRequest.removeListener(listener)
browser.webRequest.onBeforeRequest.hasListener(listener)

事件具有三个函数

addListener(listener, filter, extraInfoSpec)

向此事件添加监听器。

removeListener(listener)

停止监听此事件。listener 参数是要删除的监听器。

hasListener(listener)

检查 listener 是否注册到此事件。如果正在监听,则返回 true,否则返回 false

addListener 语法

参数

listener

当此事件发生时调用的函数。函数将传递此参数

details

object. 有关请求的详细信息。有关更多信息,请参阅 details 部分。

返回值: webRequest.BlockingResponse. 如果在 extraInfoSpec 参数中指定了 "blocking",则事件监听器应返回一个 BlockingResponse 对象,并可以设置其 cancelredirectUrl 属性。从 Firefox 52 开始,监听器可以返回一个 Promise,该 Promise 使用 BlockingResponse 解析,而不是返回 BlockingResponse。这使监听器能够异步处理请求。

filter

webRequest.RequestFilter. 限制发送到此监听器的事件的过滤器。

extraInfoSpec 可选

array of string. 事件的额外选项。你可以传递以下任何值

  • "blocking": 使请求同步,以便你可以取消或重定向请求
  • "requestBody": 在传递到监听器的 details 对象中包含 requestBody

其他对象

details

cookieStoreId

string. 如果请求来自在上下文身份中打开的标签页,则为上下文身份的 cookie 存储 ID。有关更多信息,请参阅 操作上下文身份

documentUrl

string. 将在其中加载资源的文档的 URL。例如,如果位于 "https://example.com" 的网页包含图像或 iframe,则图像或 iframe 的 documentUrl 将为 "https://example.com"。对于顶级文档,documentUrl 未定义。

frameAncestors

array. 包含从要请求的文档到顶级文档的框架层次结构中每个文档的信息。数组中的第一个元素包含有关要请求的文档的直接父级的的信息,最后一个元素包含有关顶级文档的信息。如果加载实际上是针对顶级文档,则此数组为空。

url

string. 加载文档的 URL。

frameId

integer. 文档的 frameIddetails.frameAncestors[0].frameIddetails.parentFrameId 相同。

frameId

integer. 如果请求发生在主框架中,则为零;正值是发生请求的子框架的 ID。如果(子)框架的文档被加载(typemain_framesub_frame),则 frameId 指示此框架的 ID,而不是外层框架的 ID。框架 ID 在一个标签页内是唯一的。

incognito

boolean. 请求是否来自私密浏览窗口。

method

string. 标准 HTTP 方法:例如,“GET” 或 “POST”。

originUrl

string. 触发请求的资源的 URL。例如,如果 "https://example.com" 包含链接,并且用户单击链接,则生成的请求的 originUrl 为 "https://example.com"。

originUrl 通常与 documentUrl 相同,但并非总是相同。例如,如果页面包含 iframe,并且 iframe 包含一个加载新文档到 iframe 的链接,则生成的请求的 documentUrl 将是 iframe 的父文档,但 originUrl 将是包含链接的 iframe 中的文档的 URL。

parentFrameId

integer. 包含发送请求的框架的框架的 ID。如果不存在父框架,则设置为 -1。

proxyInfo

object. 此属性仅在请求被代理时存在。它包含以下属性

host

string. 代理服务器的主机名。

port

integer. 代理服务器的端口号。

type

string. 代理服务器的类型。以下之一

  • "http": HTTP 代理(或用于 HTTPS 的 SSL CONNECT)
  • "https": 通过 TLS 连接到代理的 HTTP 代理
  • "socks": SOCKS v5 代理
  • "socks4": SOCKS v4 代理
  • "direct": 无代理
  • "unknown": 未知代理
username

字符串. 代理服务的用户名。

proxyDNS

布尔值. 如果代理将根据提供的主机名执行域名解析,则为真,这意味着客户端不应该执行自己的 DNS 查找。

failoverTimeout

整数. 故障转移超时时间(以秒为单位)。如果代理连接失败,则在此期间内不再使用该代理。

requestBody 可选

对象. 包含 HTTP 请求体数据。仅当 extraInfoSpec 包含 "requestBody" 时才提供。

error 可选

字符串. 如果在获取请求体数据时遇到任何错误,则会设置此值。

formData 可选

对象. 如果请求方法为 POST 且主体是以 UTF-8 编码的键值对序列(作为 "multipart/form-data" 或 "application/x-www-form-urlencoded"),则存在此对象。

它是一个字典,其中每个键都包含该键的所有值的列表。例如:{'key': ['value1', 'value2']}。如果数据是其他媒体类型,或者数据格式错误,则该对象不存在。

raw 可选

数组 of webRequest.UploadData. 如果请求方法为 PUT 或 POST,且主体未在 formData 中解析,则此数组包含未解析的请求主体元素。

requestId

字符串. 请求的 ID。请求 ID 在浏览器会话中是唯一的,因此您可以使用它们来关联与同一请求相关的不同事件。

tabId

整数. 发生请求的标签的 ID。如果请求与标签无关,则设置为 -1。

thirdParty

布尔值. 指示请求及其内容窗口层次结构是否为第三方。

timeStamp

数字. 此事件触发的自纪元以来的毫秒数

type

webRequest.ResourceType. 所请求资源的类型:例如,"image"、"script"、"stylesheet"。

url

字符串. 请求的目标。

urlClassification

对象. 如果请求被Firefox 跟踪保护分类,则与请求相关的跟踪类型。这是一个具有以下属性的对象

firstParty

数组 of 字符串. 请求的第一方的分类标志。

thirdParty

数组 of 字符串. 请求或其窗口层次结构的第三方的分类标志。

分类标志包括

  • fingerprintingfingerprinting_content:表示请求参与指纹识别("发现指纹识别的起源")。
    • fingerprinting 表示该域名属于指纹识别和跟踪类别。此类域名的示例包括希望将个人资料与访问用户关联的广告商。
    • fingerprinting_content 表示该域名属于指纹识别类别,但不属于跟踪类别。此类域名的示例包括使用指纹识别技术识别访问用户以进行反欺诈目的的支付提供商。
  • cryptominingcryptomining_content:类似于指纹识别类别,但用于加密采矿资源。
  • trackingtracking_adtracking_analyticstracking_socialtracking_content:表示请求参与跟踪。tracking 是任何通用的跟踪请求,adanalyticssocialcontent 后缀标识跟踪器的类型。
  • any_basic_tracking:一个元标志,它结合了跟踪和指纹识别标志,不包括 tracking_contentfingerprinting_content
  • any_strict_tracking:一个元标志,它结合了所有跟踪和指纹识别标志。
  • any_social_tracking:一个元标志,它结合了所有社交跟踪标志。

浏览器兼容性

BCD 表仅在浏览器中加载

使用 BlockingResponse 时 DNS 解析顺序

关于使用 OnBeforeRequest 时 BlockingResponse 的 DNS 解析:在 HTTP 通道中,具有阻止响应的 onBeforeRequest 发生在 DNS 解析之前,也发生在推测连接之前。对于其他通道,推测连接可能会导致 DNS 请求在 onBeforeRequest 之前发生。此顺序不是扩展程序开发人员应该依赖的,因为它可能在不同浏览器之间以及从一个浏览器版本到另一个浏览器版本,甚至从一个请求通道到另一个请求通道之间发生变化。参考 Mozilla 开发人员提供的关于 DNS 解析顺序的 BugZilla 问题说明

示例

此代码记录与<all_urls> 模式匹配的每个请求资源的 URL

js
function logURL(requestDetails) {
  console.log(`Loading: ${requestDetails.url}`);
}

browser.webRequest.onBeforeRequest.addListener(logURL, {
  urls: ["<all_urls>"],
});

此代码取消对"https://mdn.org.cn/" 下的 URL 的图像请求(要查看效果,请访问 MDN 上包含图像的任何页面,例如webRequest

js
// match pattern for the URLs to redirect
let pattern = "https://mdn.org.cn/*";

// cancel function returns an object
// which contains a property `cancel` set to `true`
function cancel(requestDetails) {
  console.log(`Canceling: ${requestDetails.url}`);
  return { cancel: true };
}

// add the listener,
// passing the filter argument and "blocking"
browser.webRequest.onBeforeRequest.addListener(
  cancel,
  { urls: [pattern], types: ["image"] },
  ["blocking"],
);

此代码通过重定向来替换对"https://mdn.org.cn/" 下的 URL 的所有网络图像请求(要查看效果,请访问 MDN 上包含图像的任何页面,例如webRequest

js
// match pattern for the URLs to redirect
let pattern = "https://mdn.org.cn/*";

// redirect function
// returns an object with a property `redirectURL`
// set to the new URL
function redirect(requestDetails) {
  console.log(`Redirecting: ${requestDetails.url}`);
  return {
    redirectUrl:
      "https://38.media.tumblr.com/tumblr_ldbj01lZiP1qe0eclo1_500.gif",
  };
}

// add the listener,
// passing the filter argument and "blocking"
browser.webRequest.onBeforeRequest.addListener(
  redirect,
  { urls: [pattern], types: ["image"] },
  ["blocking"],
);

此代码与前面的示例完全相同,只是监听器异步处理请求。它返回一个Promise,该承诺设置一个计时器,并在计时器到期时使用重定向 URL 解析。

js
// match pattern for the URLs to redirect
let pattern = "https://mdn.org.cn/*";

// URL we will redirect to
let redirectUrl =
  "https://38.media.tumblr.com/tumblr_ldbj01lZiP1qe0eclo1_500.gif";

// redirect function returns a Promise
// which is resolved with the redirect URL when a timer expires
function redirectAsync(requestDetails) {
  console.log(`Redirecting async: ${requestDetails.url}`);
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve({ redirectUrl });
    }, 2000);
  });
}

// add the listener,
// passing the filter argument and "blocking"
browser.webRequest.onBeforeRequest.addListener(
  redirectAsync,
  { urls: [pattern], types: ["image"] },
  ["blocking"],
);

另一个示例,将所有图像重定向到数据 URL

js
let pattern = "https://mdn.org.cn/*";

let image = `
  <svg xmlns="http://www.w3.org/2000/svg" width="100%" height="100%">
    <rect style="stroke-width: 10; stroke: #666;" width="100%" height="100%" fill="#d4d0c8" />
    <text transform="translate(0, 9)" x="50%" y="50%" width="100%" fill="#666" height="100%" style="text-anchor: middle; font: bold 10pt 'Segoe UI', Arial, Helvetica, Sans-serif;">Blocked</text>
  </svg>
`;

function listener(details) {
  const redirectUrl = `data:image/svg+xml,${encodeURIComponent(image)}`;
  return { redirectUrl };
}

browser.webRequest.onBeforeRequest.addListener(
  listener,
  { urls: [pattern], types: ["image"] },
  ["blocking"],
);

这是另一个版本

js
function randomColor() {
  return `#${Math.floor(Math.random() * 16777215).toString(16)}`;
}

const pattern = "https://mdn.org.cn/*";

let image = `
  <svg xmlns="http://www.w3.org/2000/svg" width="100%" height="100%">
    <rect width="100%" height="100%" fill="${randomColor()}"/>
  </svg>
`;

function listener(details) {
  const redirectUrl = `data:image/svg+xml,${encodeURIComponent(image)}`;
  return { redirectUrl };
}

browser.webRequest.onBeforeRequest.addListener(
  listener,
  { urls: [pattern], types: ["image"] },
  ["blocking"],
);

示例扩展

注意:此 API 基于 Chromium 的chrome.webRequest API。此文档来自 Chromium 代码中的web_request.json