-
Notifications
You must be signed in to change notification settings - Fork 70
Description
The webRequest.onAuthRequired
event is the only webRequest event that can block a request asynchronously in Chrome (In Firefox, all webRequest events can be async; Safari does not support any blocking webRequest API).
Firefox and Chrome have an interoperable API when an extension wants to return the result synchronously from the event handler function of webRequest.onAuthRequired
. But for asynchronous results, there is currently a large discrepancy, as I elaborated at mdn/content#30188 (review) (The permission aspect is out-of-scope for this issue, that's part of #264).
Chrome and Firefox support this syntax to handle an event synchronously:
// In Chrome: use chrome. instead of browser.
browser.webRequest.onAuthRequired.addListener(
function (details) {
return { /* BlockingResponse here*/ };
},
{ urls: ["*://example.com/*"] },
["blocking"]
);
Firefox also supports asynchronous results through a Promise. In the above example, replace "function (details) {" with "async function (details) {`, and it would be effectively the same as the following. Note that the event registration looks identical to before:
browser.webRequest.onAuthRequired.addListener(
function () {
// Does NOT work in Chrome!
return new Promise(resolve => {
resolve({ /* BlockingResponse here*/ });
});
},
{ urls: ["*://example.com/*"] },
["blocking"]
);
Chrome does not support Promise
as return value. Instead, it requires a different way to register the listener, and passing the result via a callback:
chrome.webRequest.onAuthRequired.addListener(
function (details, asyncCallback) { // listener receives "asyncCallback" parameter.
asyncCallback({ /* BlockingResponse here*/ });
// Note: any return value is ignored.
},
{ urls: ["*://example.com/*"] },
["asyncBlocking"] // "asyncBlocking" instead of "blocking"
);
I propose to update Chrome's implementation to support Promise
, with the following remarks:
- Preserve backcompat: Currently, when
asyncBlocking
is used, the return value is ignored. This should continue, in case extensions useasync function
and still callasyncCallback
asynchronously after the Promise resolves. - "blocking" is currently documented to not support anything else than an object. Chrome could support Promise as a return value like Firefox, without concerns about backwards-compatibility (because Chrome extensions can currently not expect meaningful behavior when a
Promise
is returned). - For completeness: An alternative is to introduce yet a new extraInfoSpec enum value, e.g. "asyncBlockingPromise". I see no point in doing this.