chrome.webRequest
描述: | 使用 chrome.webRequest API 監控與分析流量,還可以實時地攔截、阻止或修改請求。 |
可用版本: | 從 Chrome 17 開始支持。 |
權限: | "webRequest" 主機權限 |
清單文件
要使用網絡請求 API,您必須在應用的清單文件中聲明 "webRequest" 權限,以及您需要訪問網絡請求的所有主機的主機權限。如果您需要以阻塞方式使用網絡請求 API,您還需要另外請求 "webRequestBlocking" 權限。例如:
{ "name": "我的應用", ... "permissions": [ "webRequest", "*://*.google.com/" ], ... }
請求的生命周期
網絡請求 API 定義了一系列事件,在一次網絡請求的生命周期內產生,您可以使用這些事件監控和分析流量。某些同步事件還允許您截獲、阻止或者修改請求。
對於成功請求的事件生命周期如下圖所示,接下來是事件的定義:
-
onBeforeRequest
(可以為同步) - 當請求即將發出時產生。這一事件在 TCP 連接建立前發送,可以用來取消或重定向請求。
-
onBeforeSendHeaders
(可以為同步) -
當請求即將發出並且初始標頭已經准備好時產生。這一事件是為了使應用能夠添加、修改和刪除請求標頭
(*)。
onBeforeSendHeaders
事件將傳遞給所有訂閱者,所以不同的訂閱者都可以嘗試修改請求。有關具體如何處理的細節,請參見 實現細節部分。這一事件可以用來取消請求。 -
onSendHeaders
- 當所有應用已經修改完請求標頭並且展現最終 (*)版本時產生。這一事件在標頭發送至網絡前觸發,僅用於提供信息,並且以異步方式處理,不允許修改或取消請求。
-
onHeadersReceived
(可以為同步) - 每當接收到 HTTP(S) 響應標頭時產生。由於重定向以及認證請求,對於每次請求這一事件可以多次產生。這一事件是為了使應用能夠添加、修改和刪除響應標頭,例如傳入的 Set-Cookie 標頭。緩存指示是在該事件觸發前處理的,所以修改 Cache-Control 之類的標頭不會影響瀏覽器的緩存。它還允許您重定向請求。
-
onAuthRequired
(可以為同步) - 當請求需要用戶認證時產生。這一事件可以同步處理,提供認證憑據。注意,應用提供的憑據可能無效,注意不要重復提供無效憑據,陷入無限循環。
-
onBeforeRedirect
- 當重定向即將執行時產生,重定向可以由 HTTP 響應代碼或應用觸發。這一事件僅用於提供信息,並以異步方式處理,不允許修改或取消請求。
-
onResponseStarted
- 當接收到響應正文的第一個字節時產生。對於 HTTP 請求,這意味着狀態行和響應標頭已經可用。這一事件僅用於提供信息,並以異步方式處理,不允許修改或取消請求。
-
onCompleted
- 當請求成功處理后產生。
-
onErrorOccurred
- 當請求不能成功處理時產生。
網絡請求 API 保證對於每一個請求,onCompleted
或 onErrorOccurred
是最終產生的事件,除了如下例外:如果請求重定向至 data://
URL,onBeforeRedirect
將是最后報告的事件。
(*)注意網絡請求 API 向應用展現的是網絡棧的一種抽象。單個 URL 請求在內部可以分割為幾個 HTTP 請求(例如從一個大文件獲取單獨的字節范圍)或者可以不與網絡通信就由網絡棧處理。由於這一原因,這一 API 不會提供最終發送至網絡的的 HTTP 標頭。例如,所有與緩存相關的標頭對應用都是不可見的。
如下是當前不提供給 onBeforeSendHeaders 事件的標頭列表,這一列表不保證是完整的或者不會變化:
- Authorization
- Cache-Control
- Connection
- Content-Length
- Host
- If-Modified-Since
- If-None-Match
- If-Range
- Partial-Data
- Pragma
- Proxy-Authorization
- Proxy-Connection
- Transfer-Encoding
只有應用具有相應的主機權限時,網絡請求 API 才會暴露相關的請求。此外,只能訪問下列協議的請求:http://
、https://
、ftp://
、file://
或 chrome-extension://
。 此外,某些請求的 URL 即使使用了以上某種協議也會被隱藏。例如,chrome-extension://other_extension_id
,其中 other_extension_id
不是處理該請求的應用標識符;還有 https://www.google.com/chrome
及其他(該列表並不完整)。此外來自您的應用的同步 XMLHttpRequest 將對阻塞的事件處理函數隱藏,以免產生死鎖。注意,對於一些支持的協議,由於對應協議本身的性質,可以產生的事件會受到限制。例如,對於 file:
協議,只會產生onBeforeRequest
、onResponseStarted
、onCompleted
和 onErrorOccurred
事件。
概念
如以下幾節所述,網絡請求 API 的事件使用請求標識符,當您注冊事件監聽器時您還可以指定過濾器以及可選的額外信息。
請求標識符
每一個請求由請求標識符標識,這一標識符在瀏覽器會話以及應用的上下文中保證唯一,在請求的生命周期內保持不變,可以用來匹配同一請求的其他事件。注意在 HTTP 重定向或 HTTP 認證時,多個 HTTP 請求將映射至同一個網絡請求。
注冊事件監聽器
要為網絡請求注冊事件處理函數,您使用通常 addListener()
函數的一種變形。除了指定回調函數,您還必須指定過濾器參數,另外您還可以指定一個可選的額外信息參數。
網絡請求API的 addListener()
三個參數定義如下:
var callback = function(details) {...}; var filter = {...}; var opt_extraInfoSpec = [...];
如下是監聽 onBeforeRequest
事件的一個例子:
chrome.webRequest.onBeforeRequest.addListener( callback, filter, opt_extraInfoSpec);
每一個 addListener()
調用必須傳遞回調函數,作為第一個參數。將向這一回調函數傳遞包含當前 URL 請求詳情的詞典,詞典中的信息取決於具體事件類型以及opt_extraInfoSpec
的內容。
如果可選的 opt_extraInfoSpec
數組包含 'blocking'
字符串(僅允許用於特定事件),回調函數將以同步方式處理。這意味着請求將阻塞,直到回調函數返回。在這一種情況下,回調函數可以返回 webRequest.BlockingResponse 對象,確定這一請求進一步的生命周期。取決於當前上下文,這一響應允許取消或重定向某個請求(OnBeforeRequest
),取消請求或修改標頭(onBeforeSendHeaders
),或者提供認證憑據(onAuthRequired
)。
webRequest.RequestFilter 類型的 filter
參數允許通過不同的方式限制為哪些請求產生事件:
- URLs
-
URL 匹配表達式,例如
*://www.google.com/foo*bar
。 - 類型
-
請求類型,例如
"main_frame"
(為頂層框架加載的文檔)、"sub_frame"
(為內嵌框架加載的文檔)和"image"
(網站上的圖片)。請參見 webRequest.RequestFilter。 - 標簽頁標識符
- 某個標簽頁的標識符。
- 窗口標識符
- 某個窗口的標識符。
取決於事件類型,您可以在 opt_extraInfoSpec
中指定字符串,獲取有關請求的附加信息。這樣是為了僅在明確請求時才提供請求數據的有關詳情。
實現細節
在開發使用網絡請求API的應用時,理解如下幾個實現細節是很重要的:
沖突的解決
在網絡請求 API 的當前實現中,如果至少一個應用要求取消請求,則請求將被取消。如果一個應用取消了一個請求,所有應用都會收到 onErrorOccurred
事件的通知。一次只有一個應用允許重定向請求或者修改標頭。如果多於一個應用嘗試修改請求,最近安裝的應用具有優先級,而忽略所有其他應用。如果應用修改或重定向的要求被忽略,也不會收到通知。
緩存
百度瀏覽器使用兩種緩存:磁盤緩存和十分快速的內存緩存。內存緩存的生命周期與渲染器進程(大致與每個標簽頁對應)的生命周期相關,通過內存緩存響應的請求對網絡請求API不可見。如果請求處理函數更改了它的行為(例如根據哪些請求被阻止而作出的行為),簡單的頁面刷新不一定能夠體現這一更改的行為。要確保行為更改生效,請調用 handlerBehaviorChanged()
來清洗內存緩存。然而不要經常調用,清洗緩存是一項十分昂貴的操作。您不需要在注冊或取消注冊事件處理函數后調用 handlerBehaviorChanged()
。
時間戳
網絡請求事件的 timeStamp
屬性僅保證內部的一致性,將兩個事件的時間相比較會得到它們之間正確的時間差,但是與應用內的當前時間(例如通過 (new Date()).getTime()
)比較則可能會導致不可預料的結果。
錯誤處理
如果您使用無效的參數注冊事件,會引發 JavaScript 錯誤,事件處理程序也不會注冊。如果事件處理的過程中產生錯誤,或者事件處理程序返回無效的 BlockingResponse 對象,應用的控制台中會記錄錯誤消息,同時忽略對應請求的處理程序。
示例
如下例子演示如何阻止所有發送至 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"]);
以下例子演示如何將所有請求中的 User-Agent 標頭刪除:
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"]);
摘要
類型 | |
---|---|
RequestFilter | |
HttpHeaders | |
BlockingResponse | |
UploadData | |
屬性 | |
MAX_HANDLER_BEHAVIOR_CHANGED_CALLS_PER_10_MINUTES | |
方法 | |
handlerBehaviorChanged − chrome.webRequest.handlerBehaviorChanged(function callback) |
|
事件 | |
onBeforeRequest | |
onBeforeSendHeaders | |
onSendHeaders | |
onHeadersReceived | |
onAuthRequired | |
onResponseStarted | |
onBeforeRedirect | |
onCompleted | |
onErrorOccurred |
類型
RequestFilter
描述應用於網絡請求事件的過濾器對象。屬性 | ||
---|---|---|
array of string | urls | URL 或 URL 匹配表達式列表,不匹配任何 URL 的請求會被過濾出去。 |
array of enum of "main_frame" , "sub_frame" , "stylesheet" , "script" , "image" ,"object" , "xmlhttprequest" , or "other" |
(可選) types |
請求類型的列表,不匹配任何一種類型的請求會被過濾出去。 |
integer | (可選) tabId |
|
integer | (可選) windowId |
HttpHeaders
array of object包含 HTTP 標頭的數組,每一項標頭都通過詞典表示,包含name
屬性,以及
value
或
binaryValue
中的某一屬性。
BlockingResponse
用於在 extraInfoSpec 參數中指定 "blocking" 的事件處理函數的返回值,允許事件處理函數修改網絡請求。屬性 | ||||||||
---|---|---|---|---|---|---|---|---|
boolean | (可選) cancel |
如果為 true,則取消請求。在 onBeforeRequest 事件中使用,用來阻止請求的發送。 |
||||||
string | (可選) redirectUrl |
僅用於 onBeforeRequest 和 onHeadersReceived 事件的返回值。如果設置了該屬性,就會阻止原始請求的發送/完成,並重定向至指定的 URL。允許重定向至非 HTTP 協議的 URL,例如 data:。重定向操作產生的重定向通常使用原來的請求方法,以下情況例外:如果在 onHeadersReceived 階段產生了重定向,重定向請求將使用 GET 方法發出。 |
||||||
HttpHeaders | (可選) requestHeaders |
僅用於 onBeforeSendHeaders 事件的返回值。如果設置了這一屬性,請求將改用這些標頭發出。 |
||||||
HttpHeaders | (可選) responseHeaders |
僅用於 onHeadersReceived 事件的返回值。如果設置了這一屬性,則假定服務器返回了這些響應標頭。為了限制沖突數目(對於每一個請求,只有一個應用可以修改 |
||||||
object | (可選) authCredentials |
僅用於 onAuthRequired 事件的返回值。如果設置了這一屬性,發出的請求將使用提供的憑據。
|
UploadData
從 Chrome 23 開始支持。
包含 URL 請求中上傳的數據。屬性 | ||
---|---|---|
any | (可選) bytes |
包含數據的一份拷貝的 ArrayBuffer。 |
string | (可選) file |
包含文件路徑與名稱的字符串。 |
屬性
20 |
chrome.webRequest.MAX_HANDLER_BEHAVIOR_CHANGED_CALLS_PER_10_MINUTES |
從 Chrome 23 開始支持。 10 分鍾內handlerBehaviorChanged 能夠被調用的次數。handlerBehaviorChanged 是一個昂貴的函數,不應該經常調用。 |
方法
handlerBehaviorChanged
chrome.webRequest.handlerBehaviorChanged(function callback)
當網絡請求處理函數的行為發生更改時,為了避免緩存導致的不正確處理,需要調用這一函數。這一函數調用比較昂貴,不要經常調用。
參數 | ||
---|---|---|
function | (可選) callback |
如果您指定了 callback 參數,它應該是一個如下形式的函數: function() {...}; |
事件
onBeforeRequest
當請求即將發生時產生。
addListener
chrome.webRequest.onBeforeRequest.addListener(function callback, )
參數 | |||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
function | callback | callback 參數應該是一個如下形式的函數: function(object details) {...};
|
監聽器返回值
- ( BlockingResponse )
- 如果“extraInfoSpec”參數指定了 "blocking",事件監聽器應該返回該類型的對象。
onBeforeSendHeaders
在發送 HTTP 請求前,一旦請求標頭可用就產生這一事件。這一事件可能在與服務器的 TCP 連接建立后產生,但是確保在發送任何 HTTP 數據前產生。
addListener
chrome.webRequest.onBeforeSendHeaders.addListener(function callback, )
參數 | ||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
function | callback | callback 參數應該是一個如下形式的函數: function(object details) {...};
|
監聽器返回值
- ( BlockingResponse )
- 如果“extraInfoSpec”參數指定了 "blocking",事件監聽器應該返回該類型的對象。
onSendHeaders
當請求即將發送至服務器的前一刻產生(前面 onBeforeSendHeaders 事件處理函數作出的修改可以在這一事件產生時體現)。
addListener
chrome.webRequest.onSendHeaders.addListener(function callback, )
參數 | ||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
function | callback | callback 參數應該是一個如下形式的函數: function(object details) {...};
|
onHeadersReceived
當接收到 HTTP 響應標頭時產生。
addListener
chrome.webRequest.onHeadersReceived.addListener(function callback, )
參數 | |||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
function | callback | callback 參數應該是一個如下形式的函數: function(object details) {...};
|
監聽器返回值
- ( BlockingResponse )
- 如果“extraInfoSpec”參數指定了 "blocking",事件監聽器應該返回該類型的對象。
onAuthRequired
當接收到認證失敗時產生。事件處理函數有三種選擇:提供認證憑據,取消請求並顯示錯誤頁面,或者不采取任何行動。如果提供了錯誤的用戶憑據,可能會為同一請求重復調用事件處理函數。
addListener
chrome.webRequest.onAuthRequired.addListener(function callback, )
參數 | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
function | callback | callback 參數應該是一個如下形式的函數: function(object details, function callback) {...};
|
監聽器返回值
- ( BlockingResponse )
- 如果“extraInfoSpec”參數指定了 "blocking",事件監聽器應該返回該類型的對象。
onResponseStarted
當響應正文的第一個字節接收到時產生。對於 HTTP 請求,這意味着狀態行及請求標頭已經可用。
addListener
chrome.webRequest.onResponseStarted.addListener(function callback, )
參數 | ||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
function | callback | callback 參數應該是一個如下形式的函數: function(object details) {...};
|
onBeforeRedirect
當服務器產生的重定向即將進行時產生。
addListener
chrome.webRequest.onBeforeRedirect.addListener(function callback, )
參數 | |||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
function | callback | callback 參數應該是一個如下形式的函數: function(object details) {...};
|
onCompleted
當請求完成時產生。
addListener
chrome.webRequest.onCompleted.addListener(function callback, )
參數 | ||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
function | callback | callback 參數應該是一個如下形式的函數: function(object details) {...};
|
onErrorOccurred
當錯誤發生時產生。
addListener
chrome.webRequest.onErrorOccurred.addListener(function callback, )
參數 | ||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
function | callback | callback 參數應該是一個如下形式的函數: function(object details) {...};
|