Search code examples
javascriptfetchfirefox-addon-webextensionschrome-webrequest

WebExtension onBeforeReuest is not trigger for request from fetch API


New to web extension development & I'm trying this example. However when I run this extension it does not trigger the listener.

This is the manifest file.

{
  "description": "Altering HTTP responses",
  "manifest_version": 2,
  "name": "http-response-filter",
  "version": "1.0",
  "homepage_url": "https://github.com/mdn/webextensions-examples/tree/master/http-response",
  "permissions": [
    "webRequest",
    "webRequestBlocking",
    "http://localhost:8000/*"
  ],

  "background": {
    "scripts": ["browser-polyfill.min.js", "background.js"]
  },
  "browser_specific_settings": {
    "gecko": {
      "strict_min_version": "57.0a1"
    }
  }
}

And background.js

function listener(details) {
  console.log("event trigger"); // not reaching to here
  let filter = browser.webRequest.filterResponseData(details.requestId);
  let decoder = new TextDecoder("utf-8");
  let encoder = new TextEncoder();

  filter.ondata = (event) => {
    console.log(event.data);
    let str = decoder.decode(event.data, { stream: true });
    str = str.replace(/Example/g, "WebExtension Example");
    filter.write(encoder.encode(str));
    filter.disconnect();
  };

  return {};
}

console.log("Extension"); // this prints on the extension's console

browser.webRequest.onBeforeRequest.addListener(
  listener,
  {
    urls: ["http://localhost:8000/*"],
    types: ["xmlhttprequest", "main_frame"],
  },
  ["blocking"]
);

I found out that I need to add xmlhttprequest to the filters in order to trigger onBeforeRequest for the requests made with fetch API or XmlHttpRequest. https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/webRequest/ResourceType

I Have a sample html page runs with live-server. Here's the code snippet where I send the fetch request.

<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    <script>
      fetch("http://localhost:8000/ping")
        .then((res) => res.text())
        .then((dat) => console.log(dat))
        .catch((err) => console.log(err));
    </script>
  </body>
</html>

Any help regarding this issue is really appreciate


Solution

  • Quoting MDN:

    To intercept resources loaded by a page (such as images, scripts, or stylesheets), the extension must have the host permission for the resource as well as for the main page requesting the resource.

    So, you also need to add 127.0.0.1 in manifest.json because it's not the same as localhost, which can actually point to a different IP.

      "permissions": [
        "webRequest",
        "webRequestBlocking",
        "*://localhost/",
        "*://127.0.0.1/"
      ]