Except as otherwise noted, the content of this page is licensed under the Creative Commons Attribution 3.0 License, and code samples are licensed under the BSD License.
©2011 Google
Use the chrome.webRequest module to intercept, block,
or modify requests in-flight. This module is still experimental. For
information on how to use experimental APIs, see the
chrome.experimental.* APIs page.
You must declare the "webRequest" permission in the extension manifest to use the webRequest settings API, along with host permissions for any hosts whose network requests you want to access. If you want to use the webRequest API in a blocking fashion, you need to request the "webRequestBlocking" permission in addition. For example:
{
"name": "My extension",
...
"permissions": [
"webRequest",
"*://*.google.com"
],
...
}
The webRequest API defines the following events:
onBeforeRequest (optionally synchronous)onBeforeSendHeaders (optionally synchronous)onBeforeSendHeaders event is passed to all subscribers, so
different subscribers may attempt to modify the request, see section conflict resolution for details how this is
handled. This event can still be used to cancel the request.onSendHeadersonHeadersReceived (optionally synchronous)onAuthRequired (optionally synchronous)onBeforeRedirectonResponseStartedonCompletedonErrorOccurredonComplete or onErrorOccurred is fired as the final
event.
The life-cycle of successful requests can be illustrated as follows:
| v onBeforeRequest -------------------------------- | ^ | | [data and file URLs] | | | [redirection | | ---------- | from extension] | v | | | onBeforeSendHeaders | | | | ^ | | | v | | | | onSendHeaders | | | | | | | | | v | | | | onHeadersReceived | | | | | | | | | | | | | v | | | | | | onAuthRequired / | | | v / | | | onBeforeRedirect <---- | v | onResponseStarted <----------------------------- | v onCompletedNote that this diagram does not capture a bug that will be fixed soon: If extensions redirect a URL request via the webRequest API, this redirection does not trigger
onBeforeRedirect. Instead the request is cancelled
and a new request is started at onBeforeRedirect. See http://crbug.com/79520.
(*) Note that the webRequest API presents an abstraction of the network stack to the extension. Internally, one URL request can be split into several HTTP requests (for example to fetch individual byte ranges from a large file) or can be handled by the network stack without communicating with the network. For this reason, the API does not provide the final HTTP headers that are sent to the network. For example all headers that are related to caching are invisible to the extension.
This is a list of headers that are currently not provided to the onBeforeSendHeaders signal. The list is not guaranteed to be complete nor stable:
The signals of the webRequest API follow certain concepts and patterns that shall be described in the following.
Each request is identified by a request ID. This ID is unique within a browser session and the context of an extension. It remains constant during the the life-cycle of a request and can be used to match signals for the same request. Note that several HTTP requests are mapped to one webRequest in case of HTTP redirection or HTTP authentication.
For each signal XXX of the webRequest API, the API provides a function
chrome.webRequest.XXX.addListener() with the following
signature.
var callback = function(details) {...};
var opt_filter = {...};
var opt_extraInfoSpec = [...];
chrome.webRequest.XXX.addListener(
callback, opt_filter, opt_extraInfoSpec);
Each addListener() call takes a mandatory callback function as
the first parameter. This callback function is passed a dictionary containing
information about the current URL request. The information in this dictionary
depends on the specific event type as well as the content of
opt_extraInfoSpec.
If the optional opt_extraInfoSpec array contains the string
'blocking' (only allowed for specific signals), the callback
function is handled synchronously. That means that the request is blocked until
the callback function returns. In this case, the callback can return a BlockingResponse that determines the further
life-cycle of the request. Depending on the context, this response allows
cancelling or redirecting a request (onBeforeRequest), cancelling or
modifying headers (onBeforeSendHeaders, onHeadersReceived), or providing
authentication credentials (onAuthRequired).
Depending on the specific signal, opt_extraInfoSpec may contain
further strings that indicate that specific information shall be passed to the
extension. This is used to provide detailed information on requests data only if
explicitly requested.
The optional RequestFilter
opt_filter allows to limit the requests for which events are
triggered in various dimensions:
*://www.google.com/foo*bar.main_frame (a document that is loaded for
a top-level frame), sub_frame (a document that is loaded for an
embedded frame), image (an image on a web site) and others. See
RequestFilter.In the current implementation of the webRequest API, a request is considered as canceled if at least one extension instructs to cancel the request. If an extension cancels a request, all extensions are notified by an onErrorOccurred event. Only one extension is allowed to redirect a request or modify a header at a time. If more than one extension attempts to modify the request, the most recently installed extension wins while all others are ignored. An extension is currently not notified, if its instruction to modify or redirect has been ignored.
Chrome employs two caches, an on-disk cache and a very fast in-memory cache.
The life-time of an in-memory cache is attached to the life-time of a render
process which roughly corresponds to a tab. Requests that are answered from the
in-memory cache are invisible to the webRequest API. If a request handler
changes its behavior (for example the behavior according to which requests are
blocked), a simple page refresh might not respect this changed behavior.
chrome.webRequest.handlerBehaviorChanged() needs to be
called to flush the in-memory cache. This is a very expensive operation and
should not be done often.
It's important to note that some technical oddities in the OS's handling
of distinct Chrome processes can cause the clock to be skewed between the
browser itself and extension processes. That means that WebRequest's events'
timeStamp property is only guaranteed to be internally
consistent. Comparing one event to another event will give you the correct
offset between them, but comparing them to the current time inside the
extension (via (new Date()).getTime(), for instance) might give
unexpected results.
The following example illustrates how to block all requests to
www.evil.com:
chrome.webRequest.onBeforeRequest.addListener(
function(details) {
return {cancel: details.url.indexOf("://www.evil.com/") != -1};
},
{},
["blocking"]);
As this function uses a blocking signal handler, it requires the "webRequest" as well as the "webRequestBlocking" permission in the manifest file.
The following example achives the same goal in a more efficient way because
requests that are not targeted to www.evil.com do not need to be
passed to the extension:
chrome.webRequest.onBeforeRequest.addListener(
function(details) { return {cancel: true}; },
{urls: ["*://www.evil.com/*"]},
["blocking"]);
The following example illustrates how the User-Agent header can be deleted from all requests:
chrome.webRequest.onBeforeSendHeaders.addListener(
function(details) {
delete details.requestHeaders['User-Agent'];
return {requestHeaders: details.requestHeaders};
},
{},
["blocking"]);
Needs to be called when the behavior of the webRequest handlers has changed to prevent incorrect handling due to caching. This function call is expensive. Don't call it often.
If you specify the callback parameter, it should specify a function that looks like this:
function() {...};
Fired when an authentication failure was received. The listener has three options: it can provide authentication credentials, it can cancel the request and display the error page, or it can take no action on the challenge. If bad user credentials are provided, this may be called multiple times for the same request.
type is main_frame or sub_frame), frameId indicates the ID of this frame, not the ID of the outer frame. Frame IDs are unique within a tab.Fired when a server initiated redirect is about to occur.
type is main_frame or sub_frame), frameId indicates the ID of this frame, not the ID of the outer frame. Frame IDs are unique within a tab.Fired when a request is about to occur.
type is main_frame or sub_frame), frameId indicates the ID of this frame, not the ID of the outer frame. Frame IDs are unique within a tab.Fired before sending an HTTP request, once the request headers are available. This may occur after a TCP connection is made to the server, but before any HTTP data is sent.
type is main_frame or sub_frame), frameId indicates the ID of this frame, not the ID of the outer frame. Frame IDs are unique within a tab.Fired when a request is completed.
type is main_frame or sub_frame), frameId indicates the ID of this frame, not the ID of the outer frame. Frame IDs are unique within a tab.Fired when an error occurs.
type is main_frame or sub_frame), frameId indicates the ID of this frame, not the ID of the outer frame. Frame IDs are unique within a tab.Fired when HTTP response headers of a request have been received
type is main_frame or sub_frame), frameId indicates the ID of this frame, not the ID of the outer frame. Frame IDs are unique within a tab.Fired when the first byte of the response body is received. For HTTP requests, this means that the status line and response headers are available.
type is main_frame or sub_frame), frameId indicates the ID of this frame, not the ID of the outer frame. Frame IDs are unique within a tab.Fired just before a request is going to be sent to the server (modifications of prvious onBeforeSendHeaders callbacks are visible by the time onSendHeaders is fired).
type is main_frame or sub_frame), frameId indicates the ID of this frame, not the ID of the outer frame. Frame IDs are unique within a tab.name and either value or binaryValue.responseHeaders if you really want to modify the headers in order to limit the number of conflicts (only one extension may modify responseHeaders for each request).