google-chrome-extensionsafari-extensionchrome-extension-manifest-v3

CORS issue during HTTP request from background service worker in Safari web extension


Link to a repo with the Xcode project to test the issue: Test CORS Issue

This extension uses Manifest v3 and I have example.com in host_permissions

"host_permissions": [
        "*://example.com/*"
    ]

When I run fetch("https://example.com") in background.js I get this error:

[Error] Fetch API cannot load https://example.com/ due to access control checks.
[Error] Failed to load resource: Origin safari-web-extension://e0b5d7c7-c079-484b-8825-44d261383cb6 is not allowed by Access-Control-Allow-Origin. Status code: 200 (example.com, line 0)

Tested in both Safari Version 16.0 (17614.1.25.9.10, 17614) and Safari Technology Preview Release 153 (Safari 16.0, WebKit 17615.1.4.1)

In the code I use chrome namespace (to test it in Chrome Browser) but I get the same issue with browser namespace.

If I run this extension without any change in Chrome Browser it works perfectly (chrome://extensions/ → Load Unpacked)

Is there a way to avoid CORS issues without altering server access control settings?

Manifest v2 worked fine in this way.

Update 1:

The workaround for now to use background scripts (deprecated in v3) instead of background service worker.

Instead of this:

"background": {
        "service_worker": "background.js"
    },

Do this:

 "background": {
        "scripts": ["background.js"]
    },

Update 2: How to make your extension work for both Chrome and Safari?

Chrome supports only

"background": {
        "service_worker": "background.js"
    },

Safari supports both service_worker and scripts but when you use service_worker it has this CORS issue.

So the solution is to ship extension with different values in background field.


Solution

  • No need for workaround

    Fixed in Safari Tech Preview since Nov 5 2022
    https://github.com/nick-kadutskyi/safari-ext-cors-issue/issues/1#event-8471562656

    Fixed in Safari since 16.4

    Old workaround

    The workaround for now to use background scripts (deprecated in v3) instead of background service worker.

    Instead of this:

    "background": {
            "service_worker": "background.js"
        },
    

    Do this:

     "background": {
            "scripts": ["background.js"]
        },
    

    Update 2: How to make your extension work for both Chrome and Safari?

    Chrome supports only

    "background": {
            "service_worker": "background.js"
        },
    

    Safari supports both service_worker and scripts but when you use service_worker it has this CORS issue.

    So the solution is to ship extension with different values in background field.