问题
I have two service workers in two application on the same domain (both Angular 5):
- one inside /frontend/
- second inside /backend/
I am using @angular/service-worker package to manage service worker.
When i build prod version and deploy my applications something strange happens.
When im enter first to http://my.domain/frontend/ i can't go to http://my.domain/backend/ because service worker loading files and redirect me to http://my.domain/frontend/
What is wrong with this setup? i need to change file name of that service worker, or just i can't have two angular application on the same domain with this setup
回答1:
I had the same issue (after restarting the browser, server down - just got data from the ServiceWorker as expected, but mixed up). Then I came across this stackoverflow question and changed the names
of the assetGroups
to distinct names between all (2 in my case for now) apps.
eg:
ngws-config.json from App 1:
{
"index": "/index.html",
"assetGroups": [
{
"name": "sw-app-app",
"installMode": "prefetch",
"resources": {
"files": ["/favicon.ico", "/index.html"],
"versionedFiles": ["/*.bundle.css", "/*.bundle.js", "/*.chunk.js"]
}
},
{
"name": "sw-app-assets",
"installMode": "lazy",
"updateMode": "prefetch",
"resources": {
"files": ["/assets/**"]
}
}
]
}
ngws-config.json from App 2:
{
"index": "/index.html",
"assetGroups": [
{
"name": "sw-app-two-app",
"installMode": "prefetch",
"resources": {
"files": ["/favicon.ico", "/index.html"],
"versionedFiles": ["/*.bundle.css", "/*.bundle.js", "/*.chunk.js"]
}
},
{
"name": "sw-app-two-assets",
"installMode": "lazy",
"updateMode": "prefetch",
"resources": {
"files": ["/assets/**"]
}
}
]
}
because of:
The Cache Storage API (and other storage mechanisms, like IndexedDB) are shared throughout the entire origin, and by default there's no "sharding" or namespace segregation.
My guess is that this default names are used in the Cache Storage
for both apps (but there is also a hash, that is what still confuses me). I also checked the Cache Storage
and deleted all ngsw:* entries not containig sw-app (or sw-app-two).
After these changes everything seemed to work better but then after some reloads (with active server) I realised that my sw-app entries from the Cache Storage
where gone after opening sw-app-two
. There were only sw-app-two entries and one entry named ngsw:db:control
left. This entry only contained the assetGroups
of the sw-app-two's
ngsw-conig.json
(under manifest
). After opening sw-app again, the content in the manifest
for the assetGroups
changed to sw-app
and the sw-app-two
content was gone.
So I have ngsw:db:control
left with sw-app content, and the other Cache Storage
entry names contain sw-app-two. When I open both apps (server down) there is always sw-app-two
coming up (without errors, but it is just an app without real content). This mixup works for one app, also confusing somehow.
Some more details, but still no solution. Would love to check the angular code and make a PR but .... at least file an issue. I am quite sure the Cache Storage
gets mixed up between apps under the same origin.
PS: When you set the baseHref
be sure to check this github issues too: #8515 #8516
EDIT: I created issue #21388
EDIT(2):
Service Worker scripts must be hosted at the same origin (Protocol + Domain name + Port).
mentioned at this stackoverflow question
I will create a sub-domain for each app and run multiple http servers on different ports locally to test it. This should work and seems to be the only solution for use cases like this. Hope this is an option for you too! If not, you can write a comment to boost the freq label at the issue a bit ;-)
EDIT(3):
I found a solution that seems to work, but you have to edit the ngsw-worker.js
after the build process. Simply replace ngsw:db:
with a name that is unique for the app (eg: ngsw:db:sw-app-one:
for sw-app-one
, ngsw:db:sw-app-two:
for sw-app-two
)
EDIT(4):
Sadly the solution does not work, the entries for the control
key (eg: ngsw:db:sw-app-one:control
) will be overwritten with the content of another app ... I will comment at the issue for further details ...
回答2:
I think you're onto something with your 3rd edit @skydever.
However if you look at the deleteAllCahces
method of ngsw-worker.js
you'll find that it will delete everything that starts with the ngsw:
prefix. So instead of adding the unique app id after ngsw:
rather replace ngsw:
with ngsw-appone:
(where appone
is the unique app id for your app).
So your suggestion of editing the ngsw-worker.js
after the build seems to work, and you have to replace ngsw:
with ngsw-your_unique_app_id:
来源:https://stackoverflow.com/questions/47926704/angular-5-multiple-service-worker-in-one-domain