webRequest.onBeforeRequest
当要发出请求且在标头可用之前,会触发此事件。如果你想要取消或重定向请求,这是监听的好地方。
要取消或重定向请求,首先在 extraInfoSpec
数组参数中包含 "blocking"
到 addListener()
中。然后,在监听器函数中,返回一个 BlockingResponse
对象,设置相应的属性
- 要取消请求,请包含一个值为
true
的cancel
属性。 - 要重定向请求,请包含一个名为
redirectUrl
的属性,其值为要重定向到的 URL。
如果扩展要将公共(例如 HTTPS)URL 重定向到 扩展页面,则扩展的 manifest.json 文件必须包含一个 web_accessible_resources 键,该键列出扩展页面的 URL。
当多个阻塞处理程序修改请求时,只有一组修改生效。重定向和取消具有相同的优先级。因此,如果你取消了一个请求,如果你另一个阻塞处理程序重定向该请求,你可能会再次看到具有相同 requestId
的另一个请求。
从 Firefox 52 开始,监听器可以返回一个 Promise
,该 Promise
使用 BlockingResponse
解析,而不是返回 BlockingResponse
。这使监听器能够异步处理请求。
如果你使用 "blocking"
,则你的 manifest.json 中必须具有 "webRequestBlocking" API 权限。
语法
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
-
当此事件发生时调用的函数。函数将传递此参数
返回值:
webRequest.BlockingResponse
. 如果在extraInfoSpec
参数中指定了"blocking"
,则事件监听器应返回一个BlockingResponse
对象,并可以设置其cancel
或redirectUrl
属性。从 Firefox 52 开始,监听器可以返回一个Promise
,该Promise
使用BlockingResponse
解析,而不是返回BlockingResponse
。这使监听器能够异步处理请求。 filter
-
webRequest.RequestFilter
. 限制发送到此监听器的事件的过滤器。 extraInfoSpec
可选-
array
ofstring
. 事件的额外选项。你可以传递以下任何值"blocking"
: 使请求同步,以便你可以取消或重定向请求"requestBody"
: 在传递到监听器的details
对象中包含requestBody
其他对象
details
-
string
. 如果请求来自在上下文身份中打开的标签页,则为上下文身份的 cookie 存储 ID。有关更多信息,请参阅 操作上下文身份。 documentUrl
-
string
. 将在其中加载资源的文档的 URL。例如,如果位于 "https://example.com" 的网页包含图像或 iframe,则图像或 iframe 的documentUrl
将为 "https://example.com"。对于顶级文档,documentUrl
未定义。 frameAncestors
-
array
. 包含从要请求的文档到顶级文档的框架层次结构中每个文档的信息。数组中的第一个元素包含有关要请求的文档的直接父级的的信息,最后一个元素包含有关顶级文档的信息。如果加载实际上是针对顶级文档,则此数组为空。 frameId
-
integer
. 如果请求发生在主框架中,则为零;正值是发生请求的子框架的 ID。如果(子)框架的文档被加载(type
为main_frame
或sub_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
. 如果请求方法为 PUT 或 POST,且主体未在webRequest.UploadData
formData
中解析,则此数组包含未解析的请求主体元素。
requestId
-
字符串
. 请求的 ID。请求 ID 在浏览器会话中是唯一的,因此您可以使用它们来关联与同一请求相关的不同事件。 tabId
-
整数
. 发生请求的标签的 ID。如果请求与标签无关,则设置为 -1。 thirdParty
-
布尔值
. 指示请求及其内容窗口层次结构是否为第三方。 timeStamp
-
数字
. 此事件触发的自纪元以来的毫秒数。 type
-
webRequest.ResourceType
. 所请求资源的类型:例如,"image"、"script"、"stylesheet"。 url
-
字符串
. 请求的目标。 urlClassification
-
对象
. 如果请求被Firefox 跟踪保护分类,则与请求相关的跟踪类型。这是一个具有以下属性的对象firstParty
-
数组
of字符串
. 请求的第一方的分类标志。 thirdParty
-
数组
of字符串
. 请求或其窗口层次结构的第三方的分类标志。
分类标志包括
fingerprinting
和fingerprinting_content
:表示请求参与指纹识别("发现指纹识别的起源")。fingerprinting
表示该域名属于指纹识别和跟踪类别。此类域名的示例包括希望将个人资料与访问用户关联的广告商。fingerprinting_content
表示该域名属于指纹识别类别,但不属于跟踪类别。此类域名的示例包括使用指纹识别技术识别访问用户以进行反欺诈目的的支付提供商。
cryptomining
和cryptomining_content
:类似于指纹识别类别,但用于加密采矿资源。tracking
、tracking_ad
、tracking_analytics
、tracking_social
和tracking_content
:表示请求参与跟踪。tracking
是任何通用的跟踪请求,ad
、analytics
、social
和content
后缀标识跟踪器的类型。any_basic_tracking
:一个元标志,它结合了跟踪和指纹识别标志,不包括tracking_content
和fingerprinting_content
。any_strict_tracking
:一个元标志,它结合了所有跟踪和指纹识别标志。any_social_tracking
:一个元标志,它结合了所有社交跟踪标志。
浏览器兼容性
BCD 表仅在浏览器中加载
使用 BlockingResponse 时 DNS 解析顺序
关于使用 OnBeforeRequest 时 BlockingResponse 的 DNS 解析:在 HTTP 通道中,具有阻止响应的 onBeforeRequest 发生在 DNS 解析之前,也发生在推测连接之前。对于其他通道,推测连接可能会导致 DNS 请求在 onBeforeRequest 之前发生。此顺序不是扩展程序开发人员应该依赖的,因为它可能在不同浏览器之间以及从一个浏览器版本到另一个浏览器版本,甚至从一个请求通道到另一个请求通道之间发生变化。参考 Mozilla 开发人员提供的关于 DNS 解析顺序的 BugZilla 问题说明
示例
此代码记录与<all_urls> 模式匹配的每个请求资源的 URL
function logURL(requestDetails) {
console.log(`Loading: ${requestDetails.url}`);
}
browser.webRequest.onBeforeRequest.addListener(logURL, {
urls: ["<all_urls>"],
});
此代码取消对"https://mdn.org.cn/" 下的 URL 的图像请求(要查看效果,请访问 MDN 上包含图像的任何页面,例如webRequest)
// 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)
// 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 解析。
// 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
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"],
);
这是另一个版本
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
。