OnBeforeRequest URL redirect in Firefox Addon (Con

2019-04-11 01:12发布

问题:

I want to convert a Chrome extension of mine to Firefox. So far so good, except I had an url redirect in webRequest.onBeforeRequest in the Chrome extension, which is not allowed in Firefox WebExtensions.

Now I am unsure how to implement this in Firefox.
In the Chrome background.js it looked something like this:

chrome.webRequest.onBeforeRequest.addListener(
  function(details) {
    console.log('onBeforeRequest');

    var returnuri;
    returnuri = details.url;
    if ((details.url.indexOf("/malicious/") > -1) || (details.url.indexOf("/bad/") > -1)){
      //I want to redirect to safe content
      returnuri = details.url + (/\&tag=/.test(details.url) ? "" : '/safe/');
    }else{
      returnuri = details.url;
    }
    return {redirectUrl: returnuri};
  },
  {
    urls: [
      "*://malicious.com/*"
    ],
    types: ["main_frame"]
  },
  ["blocking"]
);

回答1:

You cite the WebExtensions docs:

Requests can be:

  • canceled only in onBeforeRequest
  • modified/redirected only in onBeforeSendHeaders

...

Redirection is not allowed in onBeforeRequest or onHeadersReceived, but is allowed in onBeforeSendHeaders.

Well, that explains the situation pretty well. Your options are:

  1. Wait until WebExtensions achieve better support for webRequest.

EDIT (Dec 2018): This is indeed now possible. Citing the documentation:

On some of these events, you can modify the request. Specifically, you can:

  • cancel the request in:
    • onBeforeRequest
    • onBeforeSendHeaders
    • onAuthRequired
  • redirect the request in:
    • onBeforeRequest
    • onHeadersReceived

[...]

  1. Cancel, and not redirect, the request if it's absolutely imperative that no connection is made at all.

  2. Redirect in onBeforeSendHeaders instead. Considering that you're only checking the URL and that is available in that event, it shouldn't make a difference except that the TCP connection may be already established before you redirect.

    Note that the same code wouldn't work in Chrome - it doesn't expect a redirect in this request.

    As mentioned by you, unlike Chrome, redirecting to the same URL would produce a loop (because at this point the request needs to be remade from scratch).

    In general, if you need to inspect something available in an earlier event and act on it later, you can flag the request in onBeforeRequest by saving its requestId and later redirecting the same request ID in onBeforeSendHeaders. Unfortunately, the docs state that requestId is not supported either.