Chrome Extension 的 webRequest模塊的解讀


文檔在此:http://developer.chrome.com/trunk/extensions/webRequest.html

1,為了使用webRequest,首先需要在配置文件manifest.json中加入類似的內容:

{
    “name": "My extension",
    ...
    "permissions": {
        "webRequest", "*://*.google.com"
    },
    ....
}

這里的意思是說,只允許這個extension對*.google.com的域名使用webRequest,如果這個字符串替換為其它格式的,比如*://*,就可以支持所有的網站訪問了。

 

2,webRequest的核心意思就是要偽造各種request,那么就不單單是寫某個對象的數據這么簡單,還需要選擇合適的時機,在發送某種request之前偽造好它,或者在真實的request到來之后半路截獲它,替換成假的然后再發出去。Life cycle of request就是描述這個事情的。

其中,onBeforeSendHeaders這個回調比較有用,文檔中如此描述“這個事件將允許extensions添加、修改或刪除request headers。簡單的用法如下:

chrome.webRequest.onBeforeRequest.addListener(
    callback, filter, opt_extraInfoSpec);

a,callback被調用時將被賦予包含request信息的一個參數。

b,filter參數是一個object,有這些key可用:

    URLs:類似這種格式的字符串:*://www.google.co/foo*bar

    Types:像main_frame或sub_frame,image這樣的類型

    TabID:tab的標識符

    WindowID:window的標識符

 

3,因為可能多個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"]);

 

5,各種API文檔

a,RequestFilter:

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
};

// 設置了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
};

HttpHeaders:HTTP headers組成的數組,數組每個元素都有自己的鍵值對,就是object了。這個得實際打印出來才知道。

b,onBeforeSendHeaders,在TCP連接建立之后和HTTP數據發送之前被調用的事件。調用方法:

chrome.webRequest.onBeforeSendHeaders.addListener(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方法
};

其它事件大同小異,調用callback時傳入的參數也都是details這個結構,只是某些字段會有不同的值。

 

6,總結:webRequest的API非常容易使用,基本上就是第四部分里三個例子的樣式。當然, 要想更好地使用,還需要Http Request的一些基礎知識,想偽造的話起碼要知道應該偽造成什么樣子才合適。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM