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 "webRequestBlocking" 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 "webRequestBlocking" 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 |