GoogleChromeLabs / sw-precache

[Deprecated] A node module to generate service worker code that will precache specific resources so they work offline.
https://developers.google.com/web/tools/workbox/guides/migrations/migrate-from-sw
Apache License 2.0
5.23k stars 389 forks source link

Making authenticated server request from client fails when opening a new window/tab #346

Open mariusk opened 6 years ago

mariusk commented 6 years ago

I've basically got a PWA with a client which works fine offline and online. When online, server API requests gets properly handled through runtimeCaching set to networkOnly. The server API carries authentication headers/cookies, and these seem to work mostly fine when using sw-precache.

But it fails IF the client tries to open a new window/tab (using window.open(.., "_blank");, where I really want the server to return a response directly in the new window/tab (a download file in this case, the functionality is "Backup").

When I press the button to take a "Backup" (generate a file on the server, returning it directly to the newly opened browser tab), a new tab gets created, but the server gets NO request from the newly created tab. When I open the developer console, the following errors are displayed:

The FetchEvent for "https://SOMEURL/api/ftapp-backup" resulted in a network error response: the promise was rejected.
Promise.catch (async)
fetchListener @ sw.js:1
sw.js:1 Uncaught (in promise) TypeError: Failed to execute 'fetch' on 'ServiceWorkerGlobalScope': 'only-if-cached' can be set only with 'same-origin' mode
    at Object.fetchAndCache (sw.js:1)
    at sw.js:1
    at <anonymous>

This error ONLY happens when I open a new tab, otherwise the client and server "pass through" to /api works just fine.

Any ideas on workarounds to avoid triggering this error?

One potential workaround could be to generate the necessary authentication information in the link to be opened and have the server try to get it from the link instead of the normal headers. But I only want to do this if I have to, I would prefer to have it just work using the regular mechanisms if possible.

mariusk commented 6 years ago

It seems my assumptions about headers etc were wrong. More likely this was related to pages being cached somewhere in the whole loading hierarchy. After some diligent data cleanup before trying new stuff - including unregistering the service worker and clearing all data - it seems to work as expected.

mariusk commented 6 years ago

Reopening as I am unable to make this work persistently. Sometimes after clearing all data it works as it should after some amount of forced reloads. Other times not. If anybody have any insights to share please do.

mariusk commented 6 years ago

Fwiw, I've done further testing and learned that whether the link is opened with window.open or a normal <a href="... > makes not difference; the serviceworker still seems to intercept the networkOnly call and fails at forwarding it to the server for some reason.

mariusk commented 6 years ago

The workaround I ended up implementing was to .fetch the data from the server, create a Blob and URL.createObjectURL, and then open this with window.open(..). At least this seems to work consistently (popup blocker issues aside).

mariusk commented 6 years ago

As mentioned earlier I managed to get it working consistently, but Chrome's popup blocker caught the windows. If I clicked the option to open it anyway it worked fine. However if I told the popup blocker to always open the window it no longer worked, and Chrome just showed a blank empty page again. For now I have given up on allowing users to download a (backup) file through my PWA and will send a file to their registered email address instead (it's not a huge amount of data).

farhaan008 commented 5 years ago

Facing the same issue angular PWA application

RotemCarmon commented 4 years ago

I have the same issue, did you ever figured it out?