Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Failed to register a ServiceWorker when PUBLIC_URL is CDN #2374

Closed
micooz opened this Issue May 26, 2017 · 11 comments

Comments

Projects
None yet
6 participants
@micooz
Copy link

micooz commented May 26, 2017

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.

@gaearon

This comment has been minimized.

Copy link
Member

gaearon commented May 26, 2017

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

This comment has been minimized.

Copy link
Contributor

jeffposnick commented May 26, 2017

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

This comment has been minimized.

Copy link
Member

gaearon commented May 26, 2017

Yep, it should be.

@Timer

This comment has been minimized.

Copy link
Collaborator

Timer commented May 26, 2017

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

This comment has been minimized.

Copy link
Contributor

jeffposnick commented May 26, 2017

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.)

@gaearon

This comment has been minimized.

Copy link
Member

gaearon commented Jun 28, 2017

@gaearon

This comment has been minimized.

Copy link
Member

gaearon commented Jun 28, 2017

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

@micooz

This comment has been minimized.

Copy link
Author

micooz commented Jun 29, 2017

All things work well, thank you all.

@VincentBel

This comment has been minimized.

Copy link

VincentBel commented Jul 28, 2017

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

This comment has been minimized.

Copy link

hartono-sulaiman-kaskus commented Sep 18, 2017

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

This comment has been minimized.

Copy link
Contributor

jeffposnick commented Sep 18, 2017

@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.)

@lock lock bot locked and limited conversation to collaborators Jan 21, 2019

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
You can’t perform that action at this time.