[chrome扩展开发] 网络请求
需要监听网络请求的话,需要先在扩展程序的清单文件中声明 webRequest
权限.需要阻塞网络请求的话需要webRequestBlocking
权限 .
可监听的网络事件有很多,他们有的addListener()
参数
var callback = function(details) {...};
var filter = {...};
var opt_extraInfoSpec = [...];
每一个 addListener() 调用必须传递回调函数,作为第一个参数。将向这一回调函数传递包含当前 URL 请求详情的词典,词典中的信息取决于具体事件类型以及 opt_extraInfoSpec 的内容。
如果可选的 opt_extraInfoSpec
数组包含 'blocking'
字符串(仅允许用于特定事件),回调函数将以同步方式处理。这意味着请求将阻塞,直到回调函数返回。在这一种情况下,回调函数可以返回 webRequest.BlockingResponse 对象,确定这一请求进一步的生命周期。取决于当前上下文,这一响应允许取消或重定向某个请求(OnBeforeRequest
),取消请求或修改标头(onBeforeSendHeaders
),或者提供认证凭据(onAuthRequired
)。
webRequest.RequestFilter 类型的 filter
参数允许通过不同的方式限制为哪些请求产生事件:
-
URL
URL 匹配表达式,例如*://www.google.com/foo*bar
。 -
类型
请求类型,例如"main_frame"
(为顶层框架加载的文档)、"sub_frame"
(为内嵌框架加载的文档)和"image"
(网站上的图片)。请参见webRequest.RequestFilter。 -
标签页标识符
某个标签页的标识符。 -
窗口标识符
某个窗口的标识符。
示例
如下例子演示如何阻止所有发送至 www.evil.com 的请求:
chrome.webRequest.onBeforeRequest.addListener(
function(details) {
return {cancel: details.url.indexOf("://www.evil.com/") != -1};
},
{urls: ["<all_urls>"]},
["blocking"]);
由于这一函数使用了阻塞事件处理函数,您将需要在清单文件中声明 "webRequest" 以及 "webRequestBlocking" 权限。
以下例子通过另一种更高效的方式达到相同目的,因为不发送至 www.evil.com 的请求不必传递给扩展程序:
chrome.webRequest.onBeforeRequest.addListener(
function(details) { return {cancel: true}; },
{urls: ["*://www.evil.com/*"]},
["blocking"]);
事件
- onBeforeRequest
- onBeforeSendHeaders
- onSendHeaders
- onHeadersReceived
- onAuthRequired
- onResponseStarted
- onBeforeRedirect
- onCompleted
- onErrorOccurred
实践
- 在
background
产生一个请求,看是否能够抓到header
chrome.webRequest.onHeadersReceived.addListener(
function(details){
console.log(details)
return {cancel: true};
},
{urls: ["*://*.baidu.com/*.png*"]},
["responseHeaders","blocking"]
);
fetch('http://www.baidu.com/img/bd_logo1.png?qua=high',{method:'get'})
.then(function(response){console.log(response)})
.catch(function(err){
console.log("Fetch错误:"+err);
});
fetch('https://www.baidu.com/',{method:'get'})
.then(function(response){console.log(response)})
.catch(function(err){
console.log("Fetch错误:"+err);
});

第一个
fetch
请求百度的logo,由于和filter
匹配上, 并且拿到header
了, 但是由于事件处理里面block
导致接下来fetch
报错.第二个
fetch
请求百度,但是由于没有匹配上filter
,所以消息处理没有收到消息.
打开百度,logo已经显示不出来了.
需要注意的事情
- filter 的 URL 匹配表达式,编写需要符合规范
- filter 除了URL,还可以过滤
tabs
或窗口,这样发挥空间比较大.