Skip to content

Failed to register a ServiceWorker when PUBLIC_URL is CDN #2374

Closed
@micooz

Description

@micooz

Can you reproduce the problem with latest npm?

Yes.

Description

When set PUBLIC_URL to a cdn address, service worker registration is blocked. It seems a cross-domain problem:

Error during service worker registration: DOMException: Failed to register a ServiceWorker: The origin of the provided scriptURL ('https://o0tu0aq0f.qnssl.com') does not match the current origin ('https://apporz.com').

Expected behavior

ServiceWorker should work well when PUBLIC_URL isn't local host.

Actual behavior

ServiceWorker doesn't work.

Environment

  1. npm ls react-scripts (if you haven’t ejected): react-scripts@1.0.6
  2. node -v: v7.10.0
  3. npm -v: v4.2.0

Then, specify:

  1. Operating system: macOS
  2. Browser and version: Chrome 58.0.3029.110 (64-bit)

Reproducible Demo

See console output on my website.

Activity

gaearon

gaearon commented on May 26, 2017

@gaearon
Contributor

cc @jeffposnick

We allow people to compile with PUBLIC_URL env variable set to a CDN (for JS and CSS assets).
Should we turn off service worker in this case?

jeffposnick

jeffposnick commented on May 26, 2017

@jeffposnick
Contributor

Ah, I wasn't aware of PUBLIC_URL. Skipping the service worker registration would be a good idea in that case, yes.

So... I guess changing this line to:

if (!process.env.PUBLIC_URL && process.env.NODE_ENV === 'production' && 'serviceWorker' in navigator) {
  // registration
}

would work? Does PUBLIC_URL get exposed in process.env like that?

gaearon

gaearon commented on May 26, 2017

@gaearon
Contributor

Yep, it should be.

Timer

Timer commented on May 26, 2017

@Timer
Contributor

AFAIK we always provide process.env.PUBLIC_URL, but by default it's a path not url.

We'd probably need to do /^[.|/]/.test(process.env.PUBLIC_URL)

jeffposnick

jeffposnick commented on May 26, 2017

@jeffposnick
Contributor

That makes sense, @Timer. You know those environment variables better than I do, so anything you think along those lines that would detect a different origin would make sense.

(I normally do this sort of thing by constructing URL objects, because they're always available inside a service worker, but I understand that URL might not be supported in all of the browsers you need to target.)

added this to the 1.0.x milestone on May 27, 2017
modified the milestones: 1.0.8, 1.0.x on Jun 26, 2017
gaearon

gaearon commented on Jun 28, 2017

@gaearon
Contributor
gaearon

gaearon commented on Jun 28, 2017

@gaearon
Contributor

(you'll need to follow migration instructions since this change won't be migrated to your project automatically)

micooz

micooz commented on Jun 29, 2017

@micooz
Author

All things work well, thank you all.

vincentbel

vincentbel commented on Jul 28, 2017

@vincentbel

Why not also use service worker when PUBLIC_URL env variable set to a CDN?

We can serve index.html and service-worker.js in our server(the same origin) and put other js/css/images assets into our CDN server. And then using service worker to cache assets in CDN server.

hartono-sulaiman-kaskus

hartono-sulaiman-kaskus commented on Sep 18, 2017

@hartono-sulaiman-kaskus

i agree with @vincentbel

i want to serve js/css/images from CDN and still want to precache them..

currently i has problem with service worker after setup PUBLIC_URL to my cdn server

lets say that i has

domain.com
cdn.domain.com/main.js

the precached files are

domain.com/index.html
domain.com/main.js
domain.com/main.css

and there are lines like this in generated service worker.js

urlsToCacheKeys.has(n));!t&&"navigate"===e.request.mode&&isPathWhitelisted(["^(?!\\/__|\\/admin\\/|\\/api\\/).*"],e.request.url)&&(n=new URL("https://cdn.domain.com/index.html"

the results are

  1. can't access https://domain.com in offline mode
  2. can access https://domain.com/index.html but the js files are not loaded
    my index.html load the cdn.domain.com/main.js
jeffposnick

jeffposnick commented on Sep 18, 2017

@jeffposnick
Contributor

@hartono-sulaiman-kaskus, what you describe is expected after #2432 went into effect.

The history behind that PR can be found upthread. There are definitely scenarios in which you can configure everything properly to safely use a service worker while retrieving all of your assets from a CDN, but doing so requires a lot of assumptions (such as: your CDN supports CORS, that the deployment of your service-worker.js and CDN happens at exactly the same time, etc.). It's not safe to make those assumptions in a general-purpose project like create-react-app.

(If you want to manually update your service worker configuration, post-eject, because you know that the way you're using a CDN is "safe" from the issues I mentioned above, then the stripPrefixMulti option allows you to remap the precached URLs.)

locked and limited conversation to collaborators on Jan 21, 2019
added a commit that references this issue on Nov 9, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

      Development

      No branches or pull requests

        Participants

        @Timer@gaearon@jeffposnick@hartono-sulaiman-kaskus@vincentbel

        Issue actions

          Failed to register a ServiceWorker when PUBLIC_URL is CDN · Issue #2374 · facebook/create-react-app