webRequest
通过webRequest系列API可以对HTTP请求进行任性地修改、定制,下面是webRequest
的几个生命周期:
这里通过beforeRequest
来简单演示一下它的冰山一角:
//manifest.json
{
// 权限申请
"permissions":
[
"webRequest", // web请求
"webRequestBlocking", // 阻塞式web请求
"storage", // 插件本地存储
"http://*/*", // 可以通过executeScript或者insertCSS访问的网站
"https://*/*" // 可以通过executeScript或者insertCSS访问的网站
],
}
// background.js
// 是否显示图片
var showImage;
chrome.storage.sync.get({showImage: true}, function(items) {
showImage = items.showImage;
});
// web请求监听,最后一个参数表示阻塞式,需单独声明权限:webRequestBlocking
chrome.webRequest.onBeforeRequest.addListener(details => {
// cancel 表示取消本次请求
if(!showImage && details.type == 'image') return {cancel: true};
// 简单的音视频检测
// 大部分网站视频的type并不是media,且视频做了防下载处理,所以这里仅仅是为了演示效果,无实际意义
if(details.type == 'media') {
chrome.notifications.create(null, {
type: 'basic',
iconUrl: 'img/icon.png',
title: '检测到音视频',
message: '音视频地址:' + details.url,
});
}
}, {urls: ["<all_urls>"]}, ["blocking"]);
几个可能经常用到的事件使用示例:
// 每次请求前触发,可以拿到 requestBody 数据,同时可以对本次请求作出干预修改
chrome.webRequest.onBeforeRequest.addListener(details => {
console.log('onBeforeRequest', details);
}, {urls: ['<all_urls>']}, ['blocking', 'extraHeaders', 'requestBody']);
// 发送header之前触发,可以拿到请求headers,也可以添加、修改、删除headers
// 但使用有一定限制,一些特殊头部可能拿不到或者存在特殊情况,详见官网文档
chrome.webRequest.onBeforeSendHeaders.addListener(details => {
console.log('onBeforeSendHeaders', details);
}, {urls: ['<all_urls>']}, ['blocking', 'extraHeaders', 'requestHeaders']);
// 开始响应触发,可以拿到服务端返回的headers
chrome.webRequest.onResponseStarted.addListener(details => {
console.log('onResponseStarted', details);
}, {urls: ['<all_urls>']}, ['extraHeaders', 'responseHeaders']);
// 请求完成触发,能拿到的数据和onResponseStarted一样,注意无法拿到responseBody
chrome.webRequest.onCompleted.addListener(details => {
console.log('onCompleted', details);
}, {urls: ['<all_urls>']}, ['extraHeaders', 'responseHeaders']);
上面示例中提到,使用webRequest
API是无法拿到responseBody
的,想要拿到的话只能采取一些变通方法,例如:
- 重写
XmlHttpRequest
和fetch
,增加自定义拦截事件,缺点是实现方式可能有点脏,重写不好的话可能影响正常页面; devtools
的chrome.devtools.network.onRequestFinished
API可以拿到返回的body,缺点是必须打开开发者面板;- 使用
chrome.debugger.sendCommand
发送Network.getResponseBody
命令来获取body内容,缺点也很明显,会有一个恼人的提示:
上述几种方法的实现方式这个链接基本上都有,可以参考下:https://stackoverflow.com/questions/18534771/chrome-extension-how-to-get-http-response-body