| OLD | NEW |
| 1 <div id="pageData-name" class="pageData">WebRequest API</div> | 1 <div id="pageData-name" class="pageData">WebRequest API</div> |
| 2 | 2 |
| 3 <!-- BEGIN AUTHORED CONTENT --> | 3 <!-- BEGIN AUTHORED CONTENT --> |
| 4 <p id="classSummary"> | 4 <p id="classSummary"> |
| 5 Use the <code>chrome.experimental.webRequest</code> module to intercept, block, | 5 Use the <code>chrome.webRequest</code> module to intercept, block, |
| 6 or modify requests in-flight. This module is still experimental. For | 6 or modify requests in-flight. This module is still experimental. For |
| 7 information on how to use experimental APIs, see the | 7 information on how to use experimental APIs, see the |
| 8 <a href="experimental.html">chrome.experimental.* APIs</a> page. | 8 <a href="experimental.html">chrome.experimental.* APIs</a> page. |
| 9 </p> | 9 </p> |
| 10 | 10 |
| 11 <h2 id="manifest">Manifest</h2> | 11 <h2 id="manifest">Manifest</h2> |
| 12 <p>You must declare the "experimental" permission in the <a | 12 <p>You must declare the "webRequest" permission in the <a |
| 13 href="manifest.html">extension manifest</a> to use the webRequest settings | 13 href="manifest.html">extension manifest</a> to use the webRequest settings |
| 14 API, along with <a href="manifest.html#permissions">host permissions</a> | 14 API, along with <a href="manifest.html#permissions">host permissions</a> |
| 15 for any hosts whose network requests you want to access. | 15 for any hosts whose network requests you want to access. If you want to |
| 16 use the webRequest API in a blocking fashion, you need to request |
| 17 the "webRequest_blocking" permission in addition. |
| 16 For example:</p> | 18 For example:</p> |
| 17 <pre>{ | 19 <pre>{ |
| 18 "name": "My extension", | 20 "name": "My extension", |
| 19 ... | 21 ... |
| 20 <b>"permissions": [ | 22 <b>"permissions": [ |
| 21 "experimental", | 23 "webRequest", |
| 22 "*://*.google.com" | 24 "*://*.google.com" |
| 23 ]</b>, | 25 ]</b>, |
| 24 ... | 26 ... |
| 25 }</pre> | 27 }</pre> |
| 26 | 28 |
| 27 <h2 id="life_cycle">Life-cycle of requests</h2> | 29 <h2 id="life_cycle">Life-cycle of requests</h2> |
| 28 | 30 |
| 29 <p> | 31 <p> |
| 30 The webRequest API defines the following events: | 32 The webRequest API defines the following events: |
| 31 <dl> | 33 <dl> |
| (...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 148 | 150 |
| 149 <p>Each request is identified by a request ID. This ID is unique within a | 151 <p>Each request is identified by a request ID. This ID is unique within a |
| 150 browser session and the context of an extension. It remains constant during the | 152 browser session and the context of an extension. It remains constant during the |
| 151 the life-cycle of a request and can be used to match signals for the same | 153 the life-cycle of a request and can be used to match signals for the same |
| 152 request. Note that several HTTP requests are mapped to one webRequest in case of | 154 request. Note that several HTTP requests are mapped to one webRequest in case of |
| 153 HTTP redirection or HTTP authentication.</p> | 155 HTTP redirection or HTTP authentication.</p> |
| 154 | 156 |
| 155 <h3 id="subscription">Subscription</h3> | 157 <h3 id="subscription">Subscription</h3> |
| 156 | 158 |
| 157 <p>For each signal XXX of the webRequest API, the API provides a function | 159 <p>For each signal XXX of the webRequest API, the API provides a function |
| 158 <code>chrome.experimental.webRequest.XXX.addListener()</code> with the following | 160 <code>chrome.webRequest.XXX.addListener()</code> with the following |
| 159 signature.</p> | 161 signature.</p> |
| 160 | 162 |
| 161 <pre> | 163 <pre> |
| 162 var callback = function(details) {...}; | 164 var callback = function(details) {...}; |
| 163 var opt_filter = {...}; | 165 var opt_filter = {...}; |
| 164 var opt_extraInfoSpec = [...]; | 166 var opt_extraInfoSpec = [...]; |
| 165 | 167 |
| 166 chrome.experimental.webRequest.XXX.addListener( | 168 chrome.webRequest.XXX.addListener( |
| 167 callback, opt_filter, opt_extraInfoSpec); | 169 callback, opt_filter, opt_extraInfoSpec); |
| 168 </pre> | 170 </pre> |
| 169 | 171 |
| 170 <p>Each <code>addListener()</code> call takes a mandatory callback function as | 172 <p>Each <code>addListener()</code> call takes a mandatory callback function as |
| 171 the first parameter. This callback function is passed a dictionary containing | 173 the first parameter. This callback function is passed a dictionary containing |
| 172 information about the current URL request. The information in this dictionary | 174 information about the current URL request. The information in this dictionary |
| 173 depends on the specific event type as well as the content of | 175 depends on the specific event type as well as the content of |
| 174 <code>opt_extraInfoSpec</code>.</p> | 176 <code>opt_extraInfoSpec</code>.</p> |
| 175 | 177 |
| 176 <p>If the optional <code>opt_extraInfoSpec</code> array contains the string | 178 <p>If the optional <code>opt_extraInfoSpec</code> array contains the string |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 217 redirect has been ignored.</p> | 219 redirect has been ignored.</p> |
| 218 | 220 |
| 219 <h2>A note about caching</h2> | 221 <h2>A note about caching</h2> |
| 220 <p> | 222 <p> |
| 221 Chrome employs two caches, an on-disk cache and a very fast in-memory cache. | 223 Chrome employs two caches, an on-disk cache and a very fast in-memory cache. |
| 222 The life-time of an in-memory cache is attached to the life-time of a render | 224 The life-time of an in-memory cache is attached to the life-time of a render |
| 223 process which roughly corresponds to a tab. Requests that are answered from the | 225 process which roughly corresponds to a tab. Requests that are answered from the |
| 224 in-memory cache are invisible to the webRequest API. If a request handler | 226 in-memory cache are invisible to the webRequest API. If a request handler |
| 225 changes its behavior (for example the behavior according to which requests are | 227 changes its behavior (for example the behavior according to which requests are |
| 226 blocked), a simple page refresh might not respect this changed behavior. | 228 blocked), a simple page refresh might not respect this changed behavior. |
| 227 <code>chrome.experimental.webRequest.handlerBehaviorChanged()</code> needs to be | 229 <code>chrome.webRequest.handlerBehaviorChanged()</code> needs to be |
| 228 called to flush the in-memory cache. This is a very expensive operation and | 230 called to flush the in-memory cache. This is a very expensive operation and |
| 229 should not be done often. | 231 should not be done often. |
| 230 </p> | 232 </p> |
| 231 | 233 |
| 232 <h2>A note about timestamps</h2> | 234 <h2>A note about timestamps</h2> |
| 233 <p> | 235 <p> |
| 234 It's important to note that some technical oddities in the OS's handling | 236 It's important to note that some technical oddities in the OS's handling |
| 235 of distinct Chrome processes can cause the clock to be skewed between the | 237 of distinct Chrome processes can cause the clock to be skewed between the |
| 236 browser itself and extension processes. That means that WebRequest's events' | 238 browser itself and extension processes. That means that WebRequest's events' |
| 237 <code>timeStamp</code> property is only guaranteed to be <i>internally</i> | 239 <code>timeStamp</code> property is only guaranteed to be <i>internally</i> |
| 238 consistent. Comparing one event to another event will give you the correct | 240 consistent. Comparing one event to another event will give you the correct |
| 239 offset between them, but comparing them to the current time inside the | 241 offset between them, but comparing them to the current time inside the |
| 240 extension (via <code>(new Date()).getTime()</code>, for instance) might give | 242 extension (via <code>(new Date()).getTime()</code>, for instance) might give |
| 241 unexpected results. | 243 unexpected results. |
| 242 </p> | 244 </p> |
| 243 | 245 |
| 244 <h2 id="examples">Examples</h2> | 246 <h2 id="examples">Examples</h2> |
| 245 | 247 |
| 246 <p>The following example illustrates how to block all requests to | 248 <p>The following example illustrates how to block all requests to |
| 247 <code>www.evil.com</code>:</p> | 249 <code>www.evil.com</code>:</p> |
| 248 <pre> | 250 <pre> |
| 249 chrome.experimental.webRequest.onBeforeRequest.addListener( | 251 chrome.webRequest.onBeforeRequest.addListener( |
| 250 function(details) { | 252 function(details) { |
| 251 return {cancel: details.url.indexOf("://www.evil.com/") != -1}; | 253 return {cancel: details.url.indexOf("://www.evil.com/") != -1}; |
| 252 }, | 254 }, |
| 253 {}, | 255 {}, |
| 254 ["blocking"]); | 256 ["blocking"]); |
| 255 </pre> | 257 </pre> |
| 256 | 258 |
| 259 <p>As this function uses a blocking signal handler, it requires the "webRequest" |
| 260 as well as the "webRequest_blocking" permission in the manifest file.</p> |
| 261 |
| 257 <p>The following example achives the same goal in a more efficient way because | 262 <p>The following example achives the same goal in a more efficient way because |
| 258 requests that are not targeted to <code>www.evil.com</code> do not need to be | 263 requests that are not targeted to <code>www.evil.com</code> do not need to be |
| 259 passed to the extension:</p> | 264 passed to the extension:</p> |
| 260 <pre> | 265 <pre> |
| 261 chrome.experimental.webRequest.onBeforeRequest.addListener( | 266 chrome.webRequest.onBeforeRequest.addListener( |
| 262 function(details) { return {cancel: true}; }, | 267 function(details) { return {cancel: true}; }, |
| 263 {urls: ["*://www.evil.com/*"]}, | 268 {urls: ["*://www.evil.com/*"]}, |
| 264 ["blocking"]); | 269 ["blocking"]); |
| 265 </pre> | 270 </pre> |
| 266 | 271 |
| 267 <p>The following example illustrates how the User-Agent header can be deleted | 272 <p>The following example illustrates how the User-Agent header can be deleted |
| 268 from all requests:</p> | 273 from all requests:</p> |
| 269 <pre> | 274 <pre> |
| 270 chrome.experimental.webRequest.onBeforeSendHeaders.addListener( | 275 chrome.webRequest.onBeforeSendHeaders.addListener( |
| 271 function(details) { | 276 function(details) { |
| 272 delete details.requestHeaders['User-Agent']; | 277 delete details.requestHeaders['User-Agent']; |
| 273 return {requestHeaders: details.requestHeaders}; | 278 return {requestHeaders: details.requestHeaders}; |
| 274 }, | 279 }, |
| 275 {}, | 280 {}, |
| 276 ["blocking"]); | 281 ["blocking"]); |
| 277 </pre> | 282 </pre> |
| 278 | 283 |
| 279 <!-- | 284 <!-- |
| 280 TODO(mkwst): update this section. We do not pass windowIds any more. | 285 TODO(mkwst): update this section. We do not pass windowIds any more. |
| (...skipping 12 matching lines...) Expand all Loading... |
| 293 if (!frameUrl[windowId]) { | 298 if (!frameUrl[windowId]) { |
| 294 frameUrl[windowId] = {}; | 299 frameUrl[windowId] = {}; |
| 295 } | 300 } |
| 296 frameUrl[windowId][tabId + "-" + frameId] = frameUrl; | 301 frameUrl[windowId][tabId + "-" + frameId] = frameUrl; |
| 297 } | 302 } |
| 298 | 303 |
| 299 function getFrameUrl(windowId, tabId, frameId, frameUrl) { | 304 function getFrameUrl(windowId, tabId, frameId, frameUrl) { |
| 300 return (frameUrl[windowId] || {})[tabId + "-" + frameId]; | 305 return (frameUrl[windowId] || {})[tabId + "-" + frameId]; |
| 301 } | 306 } |
| 302 | 307 |
| 303 chrome.experimental.webRequest.onBeforeRequest.addListener( | 308 chrome.webRequest.onBeforeRequest.addListener( |
| 304 function(d) { | 309 function(d) { |
| 305 if (d.type == 'main_frame' || d.type == 'sub_frame') { | 310 if (d.type == 'main_frame' || d.type == 'sub_frame') { |
| 306 recordFrameUrl(d.windowId, d.tabId, d.frameId, d.frameUrl); | 311 recordFrameUrl(d.windowId, d.tabId, d.frameId, d.frameUrl); |
| 307 } | 312 } |
| 308 var frameUrl = getFrameUrl(d.windowId, d.tabId, d.frameId); | 313 var frameUrl = getFrameUrl(d.windowId, d.tabId, d.frameId); |
| 309 // Use the frameUrl e.g. to selectively cancel requests. | 314 // Use the frameUrl e.g. to selectively cancel requests. |
| 310 // Attention: The frameUrl can be undefined in some cases. Requests may not | 315 // Attention: The frameUrl can be undefined in some cases. Requests may not |
| 311 // originate from a frame (e.g. requests from extensions or shared workers). | 316 // originate from a frame (e.g. requests from extensions or shared workers). |
| 312 }); | 317 }); |
| 313 | 318 |
| 314 chrome.windows.onRemoved.addListener( | 319 chrome.windows.onRemoved.addListener( |
| 315 function(windowId) {delete frameUrl[windowId];} | 320 function(windowId) {delete frameUrl[windowId];} |
| 316 ); | 321 ); |
| 317 </pre> | 322 </pre> |
| 318 --> | 323 --> |
| 319 <!-- END AUTHORED CONTENT --> | 324 <!-- END AUTHORED CONTENT --> |
| OLD | NEW |