-
Notifications
You must be signed in to change notification settings - Fork 26.2k
bug(ServiceWorker): multiple apps with ServiceWorker on one domain #21388
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
Comments
@alxhub Could this be a valid solution at db-cache.ts? export class CacheDatabase implements Database {
private cacheScope: String; // to distinct between multiple scopes
private tables = new Map<string, Promise<CacheTable>>();
constructor(
private scope: ServiceWorkerGlobalScope,
private adapter: Adapter
) {
this.cacheScope = this.scope.scope !== './' ? `:${this.scope.scope}` : '';
}
delete(name: string): Promise<boolean> {
if (this.tables.has(name)) {
this.tables.delete(name);
}
return this.scope.caches.delete(`ngsw:db${this.cacheScope}:${name}`);
}
list(): Promise<string[]> {
return this.scope.caches
.keys()
.then(keys =>
keys.filter(key => key.startsWith(`ngsw:db${this.cacheScope}:`))
);
}
open(name: string): Promise<Table> {
if (!this.tables.has(name)) {
const table = this.scope.caches
.open(`ngsw:db${this.cacheScope}:${name}`)
.then(cache => new CacheTable(name, cache, this.adapter));
this.tables.set(name, table);
}
return this.tables.get(name)!;
}
} ... but I have to provide different scopes, and the scope will always be |
found this at browser_adapter.ts: let baseElement: HTMLElement|null = null;
function getBaseElementHref(): string|null {
if (!baseElement) {
baseElement = document.querySelector('base') !;
if (!baseElement) {
return null;
}
}
return baseElement.getAttribute('href');
} it is related to the platform that is used and I don't know how to wire this up ... |
just get it in a safe way using document if available, sw are only available in the platform browser ... |
the |
I created an issue at the Angular CLI repo too. both are involved somehow, the baseHref option of the CLI needs to be passed to the service worker. I don't think that the service worker is able to do that without information from the CLI? |
replacing the |
did some more research, maybe this is helpful somehow. after renaming Afterwards I also renamed the entries |
@skydever - Did you find any solution for this? |
hi @gaurav2887 my solution was a bit hacky and I don't use it in production at the moment, but it seemed to be working - maybe you can give it a try and report your results with the current version? I created a post-build script that does some replacing in the
This way each app has unique keys for the Cache Storage and one app will not override entries from another app. I am not sure about any side effects, but the last time I tried it seemed to be working. |
@skydever - Thanks for the reply. I need something for prod as we are serving multiple apps under one domain and service worker is not working that way. |
@gaurav2887 what are the problems you are facing? do the service worker of the apps register? do you get the redirect error (always to the latest installed app)? did you try the hack I provided? maybe also relevant: #20970 #20405, AngularCLI: #8515 #8516 a possible solution could be the usage of sub domains (app1.domain.com, app2.domain.com) because then you have different origins and one app should not be able to manipulate the CacheStorage of another app... I am looking forward to production ready ServieWorker support as well ... |
@skydever - Service worker works fine for one app but does not get loaded for other app as it does not have baseHref while loading the ngsw.json for other app. So the first default root app works fine with service worker and I have to add dataGroups to ask for fresh copy of other app. We would like to use one domain and allow multiple apps loading based on the route (/app1,/app2). Making manual changes ngsw-worker.js will not be good for prod so I will probably wait for the fix which will allow us to have ngsw.json loaded per app. |
I am also seeing problems with registering multiple service workers on one domain. As it stands I'm not able to successfully register one service worker that isn't located in the root folder. I am trying to add --base-href and --deploy-url and run a node server with the app in a specified folder. The ngsw seems to configure but it doesn't cache any of the application files. |
This has more information, but it seems like a duplicate of #20405. |
Any news on this issue? This is blocking the enabling of service worker for our apps. |
Nobody is actively working on this afaict (there are other higher priority stuff going on). |
I had success with a workaround of editing the ngsw-worker.js after the build, and then replace every occurence of Then the caches prefix will be unique per app, and I'm able to switch apps without being redirected to the latest installed app. Anyone working on a pull request for this - or has it become better in Angular 7? |
I don't think anyone is working on it and neither have things changed in Angular 7 (afaik). |
suffixing the baseHref with ngsw:<base-href> string to seperate caches files app in same domain Fixes issue angular#21388
suffing baseHref with ngsw string separates the cahce files Fixes issue angular#21388
…a domain Previously, it was not possible to have multiple apps (using `@angular/service-worker`) on different subpaths of the same domain, because each SW would overwrite the caches of the others (even though their scope was different). This commit fixes it by ensuring that the cache names created by the SW are different for each scope. Fixes angular#21388
…a domain Previously, it was not possible to have multiple apps (using `@angular/service-worker`) on different subpaths of the same domain, because each SW would overwrite the caches of the others (even though their scope was different). This commit fixes it by ensuring that the cache names created by the SW are different for each scope. Fixes angular#21388
…a domain Previously, it was not possible to have multiple apps (using `@angular/service-worker`) on different subpaths of the same domain, because each SW would overwrite the caches of the others (even though their scope was different). This commit fixes it by ensuring that the cache names created by the SW are different for each scope. Fixes angular#21388
…a domain Previously, it was not possible to have multiple apps (using `@angular/service-worker`) on different subpaths of the same domain, because each SW would overwrite the caches of the others (even though their scope was different). This commit fixes it by ensuring that the cache names created by the SW are different for each scope. Fixes angular#21388
Solution proposed by @petersalomonsen also worked for me. I would suggest adding a namespace field to ngsw-config.json, which if is present when generating ngsw-worker.js is used as a postfix to all occurences of ngsw: in that file. i.e. if a namespace field is provided in ngsw-config.json with a value of "my-app", then perform a find/replace on ngsw-worker.js post generation (or during) replacing all occurences of ngsw: with ngsw-my-app: allowing this namespace value to be provided in tooling would also be useful. e.g. as a question when performing ng add @angular/pwa |
@canhamd Evolved this a bit and created this script that I run after building the production bundles. It creates an unique app id by hashing the value of the index property in
|
I don't think adding a value to The SW scope should be used instead. In case anyone has missed it, there is a PR in progress for that: #27080 |
@gkalpak Correcting myself - I meant the |
…a domain Previously, it was not possible to have multiple apps (using `@angular/service-worker`) on different subpaths of the same domain, because each SW would overwrite the caches of the others (even though their scope was different). This commit fixes it by ensuring that the cache names created by the SW are different for each scope. Fixes angular#21388
…a domain Previously, it was not possible to have multiple apps (using `@angular/service-worker`) on different subpaths of the same domain, because each SW would overwrite the caches of the others (even though their scope was different). This commit fixes it by ensuring that the cache names created by the SW are different for each scope. Fixes angular#21388
…a domain Previously, it was not possible to have multiple apps (using `@angular/service-worker`) on different subpaths of the same domain, because each SW would overwrite the caches of the others (even though their scope was different). This commit fixes it by ensuring that the cache names created by the SW are different for each scope. Fixes angular#21388
…a domain Previously, it was not possible to have multiple apps (using `@angular/service-worker`) on different subpaths of the same domain, because each SW would overwrite the caches of the others (even though their scope was different). This commit fixes it by ensuring that the cache names created by the SW are different for each scope. Fixes angular#21388
…a domain Previously, it was not possible to have multiple apps (using `@angular/service-worker`) on different subpaths of the same domain, because each SW would overwrite the caches of the others (even though their scope was different). This commit fixes it by ensuring that the cache names created by the SW are different for each scope. Fixes angular#21388
🎉 awesome!! thx a lot to everybody involved in this 👍 |
it still don't work! |
@Kush5900 what version have you tried it on? |
@tplk Yeah i'm on 7.2 and i'am working on a serious project can't update to beta versions! i'm currently using @petersalomonsen work around but it seems unstable somehow. any alternative? |
@Kush5900 Are you using my workaround as in the script below? I'm running this using the dist folder as argument after building the bundles.
|
@pedroclayman Yeah i copied the whole script and it works and i'm able to switch between languages but since then my serviceWorker stopped working in offline mode! How are you registering the service worker in app.module.ts ? |
I register my serviceworker like this:
No absolute path. My apps work fine in offline mode. @Kush5900 |
@petersalomonsen that it is how i register my serviceworker too, sometimes it works and sometimes it produce these error:
|
hmmm, I'm not experiencing that @Kush5900 but will let you know if I do. |
…a domain (angular#27080) Previously, it was not possible to have multiple apps (using `@angular/service-worker`) on different subpaths of the same domain, because each SW would overwrite the caches of the others (even though their scope was different). This commit fixes it by ensuring that the cache names created by the SW are different for each scope. Fixes angular#21388 PR Close angular#27080
This issue has been automatically locked due to inactivity. Read more about our automatic conversation locking policy. This action has been performed automatically by a bot. |
I'm submitting a...
Current behavior
The installation of a 2nd App/ServiceWorker (with different baseHref) purges the Cache Storage entries for a previously installed App/ServiceWorker, if they are on the same domain. This breaks the 1st installed App. It is not reachable anymore - you will always be redirected to the latest installed App.
Expected behavior
The installation of multiple Apps/ServiceWorkers (with different baseHref) on one domain should be possible.
Minimal reproduction of the problem with instructions
I created the following repo to reproduce the issue: https://github.com/skydever/repro-multiple-ng-apps-one-domain-serviceworker. Follow the steps of the README there.
What is the motivation / use case for changing the behavior?
I have to deploy multiple Angular Apps on one domain.
Environment
The text was updated successfully, but these errors were encountered: