chrome 插件开发 webRequest 网络请求[6]
添加权限 对象获取
//manifest.json
"permissions": [
"webRequest",
"webRequestBlocking"
],
"background": {
"persistent": true // false时 The 'webRequest' API cannot be used with event pages.
}
此时便可以获到chrome.webrequest对应了
chrome.webRequest
实例
拦截百度png文件
chrome.webRequest.onHeadersReceived.addListener(
function(details){
console.log('onHeadersReceived',details) //请求baidu .png文件时会拦截
//onHeadersReceived {frameId: 0, initiator: "chrome-extension://agkllkkjbhclhjnlebdbdagkagfgcecj", method: "GET", parentFrameId: -1, requestId: "72074", …}
return {cancel: true};
},
{urls: ['*://*.baidu.com/*.png*']},
['responseHeaders','blocking']
);
//请求百度的logo图片 会拦截
fetch('https://www.baidu.com/img/bd_logo1.png',{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);
});
details参数
第三个参数 ['blocking']只为blocking去掉responseHeaders
api说明
webRequest的核心意思就是要伪造各种request,那么就不单单是写某个对象的数据这么简单,还需要选择合适的时机,在发送某种request之前伪造好它,或者在真实的request到来之后半路截获它,替换成假的然后再发出去。Life cycle of request就是描述这个事情的。
其中,onBeforeRequest这个回调比较有用,文档中如此描述“这个事件将允许extensions添加、修改或删除request headers。简单的用法如下:
chrome.webRequest.onBeforeRequest.addListener(callback, filter, opt_extraInfoSpec);
callback
callback被调用时将被赋予包含request信息的一个参数。
callback :function(object details) {...})
其中,传给callback的参数details结构如下:
details = {
tabId: integer, //如果没有和tab关联则返回-1
parentFrameId: integer,
url: string,
timeStamp: double,
//0表示request是在main frame里发生的
frameId: integer,
requestId: string,
requestHeaders: HttpHeaders, // optional
type: enumerated_string, //value in: ["main_frame", "sub_frame", "stylesheet", "script", "image", "object", "xmlhttprequest", "other"]
method: string //标准HTTP方法
};
//返回值
// 设置了blocking关键字的就用这个object来作为block的规则了
BolockingResponse = {
//为true的话request被cancel,在onBeforeRequest里面用哦
cancel: boolean, //optional
//只在onBeforeRequest事件中使用,用来掉包的关键属性!!!
redirectUrl: string, //option
//只用在onHeadersReceived事件里,在浏览器返给server时把header给掉包
responseHeaders: HttpHeaders //optional
//只在onBeforeSendHeaders事件中使用。是另一个用来掉包的关键属性!!!
requestHeaders: HttpHeaders //optional
//只在onAuthRequred事件中使用,当然也是用来掉包的
authCredentials: object //optional
};
filter
filter参数是一个object,有这些key可用:
URLs:类似这种格式的字符串:*://www.google.co/foo*bar
Types:像main_frame或sub_frame,image这样的类型
TabID:tab的标识符
WindowID:window的标识符
RequestFilter = {
tabId: interger, //optional
//URL的数组,或者是匹配URL的pattern
urls: array_of_string,
//可选的值有:"main_frame", "sub_frame", "stylesheet", "script", "image", "object", "xmlhttprequest", "other"
types: array_of_enumerated_string, //optional
windowId: integer //optional
};
opt_extraInfoSpec 控制回调函数参数的值 不同的回调
["blocking"]
//'extraHeaders' 'responseHeaders' 等
因为可能多个extension都要玩webRequest,所以需要一套冲突处理机制。如果设置了新的request,刷新页面后是否设置继续有效,设置了之后什么时候有效,这些都是关于cache的问题。另外就是使用timestamp属性的问题,凡从timestamp取得的属性值,相互之间可以比较,但是如果和new Date().getTime()这种方式取得的值比较就不一定对了,需要加以注意。
4,例子
a,阻止所有发往www.evile.com的request
chrome.webRequest.onBeforeRequest.addListener(
function(details) {
return {cancel: details.url.indexOf("://www.evil.com/") != -1};
},
{urls: ["<all_urls>"]},
["blocking"]);
另一种方法,使用filter:
chrome.webRequest.onBeforeRequest.addListener(
function(details) { return {cancel: true}; },
{urls: ["*://www.evil.com/*"]},
["blocking"])
符合filter的都被cancel掉了。
b,从所有的request中删除User-Agent的header
chrome.webRequest.onBeforeSendHeaders.addListener(
function(details) {
for (var i = 0; i < details.requestHeaders.length; ++i) {
if (details.requestHeaders[i].name === 'User-Agent') {
details.requestHeaders.splice(i, 1);
break;
}
}
return {requestHeaders: details.requestHeaders};
},
{urls: ["<all_urls>"]},
["blocking", "requestHeaders"]);
常用拦截函数
image.pngonBeforeRequest
onBeforeSendHeaders
onSendHeaders
onHeadersReceived
onAuthRequired
onResponseStarted
onBeforeRedirect
onCompleted
onErrorOccurred
filter urls 拦截规则
A match pattern is essentially a URL that begins with a permitted scheme (http, https, file, or ftp, and that can contain '*' characters. The special pattern <all_urls> matches any URL that starts with a permitted scheme. Each match pattern has 3 parts:
scheme — for example, http or file or *
Note: Access to file URLs isn't automatic. The user must visit the extensions management page and opt in to file access for each extension that requests it.
host — for example, www.google.com or .google.com or ; if the scheme is file, there is no host part
path — for example, /, /foo, or /foo/bar. The path must be present in a host permission, but is always treated as /*.
Here's the basic syntax:
<url-pattern> := <scheme>://<host><path>
<scheme> := '*' | 'http' | 'https' | 'file' | 'ftp'
<host> := '*' | '*.' <any char except '/' and '*'>+
<path> := '/' <any chars>
The meaning of '*' depends on whether it's in the scheme, host, or path part. If the scheme is *, then it matches either http or https, and not file, or ftp. If the host is just *, then it matches any host. If the host is .hostname, then it matches the specified host or any of its subdomains. In the path section, each '' matches 0 or more characters. The following table shows some valid patterns.
Here are some examples of invalid pattern matches:
image.png