Modify headers with declarativeNetRequest.updateSessionRules()?

Hello,

I try to modify the HTTP request headers with declarativeNetRequest.updateSessionRules(), but it doesn’t work.

  • manifest.json

    {
      "manifest_version": 2,
      "name": "Test case",
      "version": "1.0.0",
      "background": {
        "page": "page.html",
        "persistent": true
      },
      "permissions": [
        "<all_urls>",
        "declarativeNetRequest"
      ]
    }
    
  • page.html

    <!doctype html>
    <html>
      <head>
        <meta charset="utf-8" />
        <title>Test case</title>
      </head>
      <body>
        <script src="script.js" type="module"></script>
      </body>
    </html>
    
  • script.js

    await browser.declarativeNetRequest.updateSessionRules({
      addRules: [
        {
          action: {
            type: "modifyHeaders",
            requestHeaders: [
              {
                header: "X-Foo",
                value: "bar",
                operation: "set",
              },
            ],
          },
          condition: {
            urlFilter: "httpbin",
          },
          id: 1,
        },
      ],
    });
    

When I go to https://httpbin.org/headers, I don’t see the X-Foo header. Can you see why my extension does nothing?

It works after this change:

condition: {
  resourceTypes: [ "main_frame" ],
  urlFilter: "httpbin",
},
1 Like

Thanks for the solution, it works with the resourceTypes property. This property is optional, so I thought that if you didn’t set it: there was no filter.

The final objective of my extension is to bypass the CORS of requests coming from an HTML page in a local file. I’m stuck again with the following code:

  • manifest.json

    {
      "manifest_version": 2,
      "name": "Test case",
      "version": "1.0.0",
      "background": {
        "page": "page.html",
        "persistent": true
      },
      "permissions": [
        "<all_urls>",
        "file:///*",
        "declarativeNetRequest"
      ]
    }
    
  • page.html

    <!doctype html>
    <html>
      <head>
        <meta charset="utf-8" />
        <title>Test case</title>
      </head>
      <body>
        <script src="script.js" type="module"></script>
      </body>
    </html>
    
  • script.js

    await browser.declarativeNetRequest.updateSessionRules({
      addRules: [
        {
          action: {
            type: "modifyHeaders",
            requestHeaders: [
              {
                header: "X-Foo",
                value: "bar",
                operation: "set",
              },
            ],
          },
          condition: {
            resourceTypes: ["main_frame", "xmlhttprequest"],
            urlFilter: "httpbin",
          },
          id: 1,
        },
      ],
    });
    

When I run await fetch("https://httpbin.org/headers"); in DevTools:

  • of a local page (file:///home/regseb/baz.html): there’s no X-Foo header.
  • from the https://perdu.com/ page (any http page): the X-Foo header is added.
1 Like

I don’t know if browser.declarativeNetRequest can modify the request headers when you:

  1. Open a local HTML file
  2. Open the DevTools (Ctrl-Shift-I) and switch to the Console
  3. Run this line in the console:
    await fetch("https://httpbin.org/headers");

If you put the HTML and the JS in separate files, then Firefox doesn’t let you do this.

local.html

<!doctype html>
<html>
  <head>
    <meta charset="utf-8" />
    <title>Local Page</title>
  </head>
  <body>
    <script src="local.js" type="module"></script>
  </body>
</html>

local.js

await fetch("https://httpbin.org/headers");

When you open local.html in Firefox, the console shows the error:

Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at file:///home/hans/local.js. (Reason: CORS request not http).
[More Information]

You’d have to use an inline script:

local.html

<!doctype html>
<html>
  <head>
    <meta charset="utf-8" />
    <title>Local Page</title>
  </head>
  <script>
    (async () => {
      let result = await fetch("https://httpbin.org/headers");
      console.log(result);
    })();
  </script>
</html>

But even then, I don’t know how you could convince browser.declarativeNetRequest to modify the headers.

To summarize my project Gout, it’s a dashboard (mainly RSS feeds). The user creates an HTML file locally. In the HTML document, he configures the widgets in <script type="application/json"> tags. The program loads the widgets’ source code with the jsDelivr CDN. The widgets use fetch() to retrieve RSS feeds, so CORS must be bypassed. I’ve developed a working extension, but it uses webRequest. I’m trying to migrate to declarativeNetRequest to have the same source code for Firefox and Chrome.

The documentation doesn’t mention any limitation for local files; and it works under Chrome. So I opened a issue.

Thanks for opening bug 1887869, @regseb. I looked into it as best I could and added a comment to the issue.

1 Like