angular: [ServiceWorker] localhost took too long to respond. HTTP ERROR 504

I’m submitting a…

[x] Bug report

Minimal reproduction of the problem with instructions

  1. ng new sw --service-worker --routing
  2. cd sw
  3. ng g c home
  4. ng g c about
  5. Edit app-routing.module.ts to add the routes for the 2 components we’ve just created:
// ...
import { HomeComponent } from './home/home.component';
import { AboutComponent } from './about/about.component';

const routes: Routes = [
  { path: '', component: HomeComponent },
  { path: 'about', component: AboutComponent }
];

// ...
  1. ng build --prod
  2. npm install -g http-server (you can use any server to test this, if you already prefer another one)
  3. http-server dist
  4. Access localhost:8080 (8080 is the default port that http-server uses at the time of reporting this issue)
  5. Access localhost:8080/about
  6. Stop the server
  7. Now try reloading the app while on the /about route (if it works the first time, try refreshing a few more times or wait a little before trying again). The browser will display the message:
This page isn’t working
localhost took too long to respond.
HTTP ERROR 504

(With Universal/SSR, it stops working right away, most of the time with the first refresh after stopping the server, no matter the route - and the issue is not the hash in the generated ngsw.json, because I regenerate that at the end of the build process).

Now, if you start the server again, loading the app on the /about route works (even though http-server is not SPA friendly, it doesn’t redirect all requests to index.html), but the service worker kicks in. Initially I noticed this behavior on a Universal app, doing server side rendering (following the universal-starter repo). So this is not a http-server “not being SPA friendly” issue. I only used http-server to reproduce it because I wanted to keep the reproduction process as fast as possible, without introducing server side rendering. The CLI version used (1.6.4) initializes the app with Angular 5.1.0, but I’ve also tested on 5.2.1. I’ve skipped mentioning this step above because it happens regardless of the Angular version (at least on >= 5.1.0, haven’t tested with older versions).

Environment

Angular CLI: 1.6.4
Node: 8.9.4
OS: win32 x64
Angular: 5.2.1

Browser:
I've only tested on:
- [x] Chrome (desktop) version 63.0.3239.132
- [x] Chrome (desktop) version 65.0.3323.2 (canary)

About this issue

  • Original URL
  • State: closed
  • Created 6 years ago
  • Reactions: 23
  • Comments: 72 (15 by maintainers)

Commits related to this issue

Most upvoted comments

I’ve been able to figure out two issue spots, that when worked around in my app, allow it to work offline. I won’t go into full detail here; I’ve given a long explanation on this SO answer.

  1. Hosted versions of an Angular app, where the --base-href flag is set from the CLI, list absolute URLs for their service worker resources. When comparing requests to these resources, ngsw-worker.js is expecting relative URLs
  2. Of the 3 available “states” that the ngsw-worker.js can be in, in my experience, EXISTING_CLIENTS_ONLY seems to bet set incorrectly.

(source code links are in the SO answer; I can duplicate them here as well)

My current workaround is running this build script, after ng build -prod and before http-server. If you can, give it a shot and see if it works for you? I’m trying to work on a pull request (# 1 above can definitely be fixed in the source, # 2 needs more investigation to avoid breaking anything); currently stymied by setting up a dev environment for the @angular/service-worker package

Final note: you can see my app working offline in this repo (using the build script at this line), and you can see a clone of that repo from the time where I was having the issue (so it still fails offline) here

I’m voting this issue to be reopened.

Did anyone get this fixed? I’m having this issue in Apr 19 on Angular 7.

During testing of the issue, I’ve recreated the exact problem explained by @MrCroft in a repro here, to ensure that it exists even with the simplest app from ng new app-name --service-worker. Still trying to dig into where the fetching fails in ngsw-worker.js.

Any updates on the aforementioned issues?

We should reopen this one.

@jrcasso @zuschy guys (or girl) it’s an open-source project.

First, thank people that have given time building it so you do not have to do it yourself.

Second, if you think it should be improved, and have idea how to do it, open issues/PRs. You have the right to look at the service code, it’s not that hard.

Finally, if this code does not match your needs, there is other pre-written service workers out there which work fine with Angular.

I personnally think the Angular service worker have some unique concepts that makes it powerfull (no need to skipWait() between app versions, multiple app versions in parrallel, nice self-hosted debug page /ngsw/state, in-app service to control it, etc), but you have to be meticulous at configuring it.

If there are bugs, your comments certainly does not help fixing them.

Same issue, Angular 8

I’m getting the same issue with Angular 7.

Offline mode works great in Firefox. In Chrome, offline mode gives me a 504. Everything passes in the Chrome Lighthouse (Audit) tools.

It doesn’t work on my Android phone either (Standalone or Chrome browser). Not sure what the issue could be. I am using hash routing.

@H--o-l To be honest, I haven’t checked lately if the same reproduction steps still apply, or if people are running into this in some more specific scenarios. I guess it doesn’t bother me that much because I don’t have any apps that truly need to work offline, I only use the ServiceWorker to benefit from faster load times (after that first load, when it builds the cache, of course).

if you think it should be improved, and have idea how to do it, open issues/PRs. You have the right to look at the service code, it’s not that hard.

As simple as it may look for some, other people surely either don’t have the time or the understanding of what’s going on there. I tend to understand people’s frustration, if an issue has been marked as resolved but it’s still happening for them. As long as they’re not hateful, I usually “thumbs up” comments that report the issue still happening. I always thought that reopening an issue is better than opening a new one, identical to an existing one. But that’s just my opinion.

if this code does not match your needs, there is other pre-written service workers out there which work fine with Angular.

I don’t think this is about “needs matching”. As long as the app loads in offline mode when accessing / and doesn’t load when accessing /some/route/ (and we’re not talking about a misconfigured server - especially if we’re “offline”, that wouldn’t even matter, since we don’t even reach the server), that seems like a bug. If I really needed my apps to “fully” work offline, I guess this would be frustrating for me as well, to have the issue resolved/closed, but the reported behavior still happening.

I personally think the Angular service worker have some unique concepts that makes it powerfull […]

Agree! I guess that’s why people prefer the built-in option, rather than 3rd party solutions. But, like I said, not everybody has the time or understanding to be able to come with bug fixes, improvements etc. I don’t think that they don’t appreciate the team, the contributors, the community. Maybe just lacking expressing gratitude sometimes or (like me) thinking it’s iimplied automatically.

First, thank people that have given time building it so you do not have to do it yourself.

That being said, I always thought that big “thank you” 's are implied 😃. Surely, every developer using it is grateful for everything that the Angular framework (or, rather, the entire ecosystem) does for us, grateful for everything that the core team and every contributor is doing, and for the whole community. But I guess you’re right, not saying it makes it seem like it’s not appreciated enough.

Just tested with Angular 6.0.0-rc.1 and CLI 6.0.0-rc.1 This still happens.

> ng new ng6
> cd ng6
> ng g serviceWorker --project ng6
> npm install --save @angular/service-worker@6.0.0-rc.1
> npm run build
> http-server dist/ng6/

I did unregister all service workers from localhost first (from chrome dev tools) before doing the above steps, so there were no left-overs.

image

Thx, everyone, for your input. AFAICT, there are several issues discussed here. From what I understand, these are:

  1. SW doesn’t work correctly when going offline.
  2. SW doesn’t work correctly with --base-href.
  3. Some other issue (possibly related to/the same as 1) that affects universal apps.

#22883 should address the offline issue, which seems to be the main issue mentioned by the OP. Thx, @jackkoppa, for the detailed explanation of what is going on. This helped a lot while investigating the problem.

The issue related to --base-href is not clear to me (e.g. what exactly is the issue, how to reproduce). @jackkoppa, I saw you said you are going to work on that. If the problem still exists and if you want me to look into it, please open a new issue (or point me to an existing one), providing the necessary details (e.g. a minimal reproduction).

Same goes for the universal-related issue (if it is not fixed by #22883).

BTW, let's keep discussions here focused on the offline bug (and open separate issues for different problems), because it is confusing to talk about unrelated bugs on a single thread.

What appears to be happening is that when you go offline, if you then hit reload chrome creates a new client. This renders the app from cache. Within a second or two of that happening ngsw-worker.js sends a request to get ngsw.json (to check whether there is an update to any of the code) this fails (because there is no network). On failing it sets the state of the worker to EXISTING_CLIENTS_ONLY. If you hit reload again then another new client is created and fails to render. This behaviour seems consistent. There are a few hits on google with regard to the problem being related to having dev tools open or that it is a timing issue. There is a timing issue in that if you hit refresh a series of times quickly after you have gone offline the call to ngsw.json doesn’t get chance to fail and set EXISTING_CLIENTS_ONLY so the page continues to renders. If you take a deep breath before hitting refresh it will then fail. If rather than hitting reload, you navigate off the page and back on it works, if your app is more complex and you stay in the app and navigate around it also should also work disconnected.

If you want to see the current state open a tab and navigate to <base path>/ngsw/state. To reset the state you can stop and start the worker in devtools.

I think the reason this is coming up as a problem is because people are creating a basic app to test this functionality and the easiest way to check is to hit reload after going off line, which then breaks it.

It would seem sensible to allow users to hit reload of an existing client without the sw switching states as I would imagine that would happen a lot, so hopefully this will get revisited. There are some notes in the code about why it works like it does so it looks like this is by design rather than a bug.

Getting exact same 504 error with API request setup in datagroups. Because of this while my audit mentions everything to be perfect with respect to PWA service worker, i am unable to run my application in offline mode.

Same issue, Angular 8 also. Lazy-loaded feature modules, the works.

Service Workers are a constant pain in my ass with Angular.

For example, as a test, I have one of my dataGroups caching all PHP requests: { "name": "test", "urls": [ "/**/*.php" ], "version": 0, "cacheConfig": { "maxSize": 200, "maxAge": "7d", "timeout?": "3s", "strategy": "freshness" } }

…and not a single call to my PHP API is cached. It feels like every time I rebuild a branch for an enterprise production master, the service worker may or may not cache GET requests for offline PWA usage, for reasons that are seemingly arbitrary. It’s debilitating, frustrating, and dysfunctional.

I have the same issue. 504 when offline in Chrome, it works when I try in Firefox. Has anyone else tried in Firefox?

@H--o-l don’t get me wrong, I agree with you.

But sometimes it appears, that the service worker arbitrary does or does’t cache requests. I built the same code, serveral times, on different servers, but the behavior is never the same. I try continuously to find the right configuration, but the behavior of the service worker isn’t clearly reproducible, this is frustrating. Sometimes it’s good to know, that you’re not alone with a problem like that.

That doesn’t mean, that we doesn’t try to find a way to fix the bug! 😉

Thanks for this comment! For a long time, I thought, I’m the only one who feels like that!

Thx for the detailed response, @MrCroft. This might be an issue with the new cli. @MrCroft, @jkossis: Let’s track this in #23240.

@jackkoppa fix-sw,js not complete work for me, but I referred to it and made another one

I’m with the same error here, when I’m online I can see a lot of things being loaded by the service worker, but when I turn into online, nothing is loaded.

image

I have the same issue ad Tom and others. Offline in Firefox is ok on desktop. On android FF refresh shows a blank page, but a browse to the page in Offline mode works. In Chrome, it just shows the 504 on desktop or android.

My code is available here: https://github.com/deniszholob/angular-app-template

chrome_2019-02-21_19-01-51

==========

Now i did get it to work locally, using http-server but only after I hit refresh a couple times, then go offline. (while using incognito mode, why the requirement for a couple refreshes then???)

1st offline refresh, this time actually only didnt load images

chrome_2019-02-21_18-58-06

Then after going live and hitting a refresh a couple times then going offline and hitting refresh only thing that didnt load is font awesome. chrome_2019-02-21_18-58-29

I figured out my issue, after spending time debugging the ngsw-worker.

During my automated release, I replace some tokens in my “/assets/data/config.json” file. So the hash in the hash table is incorrect once the application is deployed. This causes the state to be set to DriverReadyState.EXISTING_CLIENTS_ONLY and the file is never recovered from cache.

As a temporary workaround, I’ve commented out this.state = DriverReadyState.EXISTING_CLIENTS_ONLY; in the ngsw-worker file. Now offline mode works great.

I’m now modifying my ngsw-worker as a post build step as suggested above by @jackkoppa . https://github.com/angular/angular/issues/21636#issuecomment-366205459

I can confirm Cloudflare minification affects offline mode. Make sure you purge cache as well when you disable them.

@gkalpak The service worker is turned on (I’ve checked both “angular.json” for serviceWorker: true and the generated dist folder for ngsw-worker.js) and it is enabled in app.module (ServiceWorkerModule.register('/ngsw-worker.js', { enabled: environment.production })). I think the command ng g serviceWorker --project ng6 did all that, because I don’t remember doing it myself. Also checked the network tab, when server is running it says “from ServiceWorker”. I also don’t think it would be a 504 otherwise.

Anyway, just tried with 6.0.0-rc.2 (both Angular and the CLI), it’s still happening but I wasn’t sure if I should open another issue, because it’s actually the same issue (this one). I thought it should be re-opened rather than re-created. I’ve opened one now: #23240

P.S. About the --service-worker flag, I think it’s no longer part of ng new. I did try that initially and got no result. Also, not listed under ng new --help so that’s when I’ve found ng g serviceWorker. Also, when I tried with rc.1, the build script in package.json was ng build --prod that’s why I simply ran npm run build instead of ng build --prod myself (in case anybody’s wondering). Now I see the “build” script is back to ng build, so with rc.2 I had to run ng build --prod myself.

@MrCroft, you don’t seem to have turned Service Worker on (via the --service-worker flag). Please make sure you have Service Workers turned on and working in the app and if you still have issues with offline mode, open a new issue providing the necessary info (e.g. a minimal reproduction). Thx!

In my opinion, offline means offline. Not “offline, but only if you open a fresh tab, not when hitting refresh”. I don’t think that’s the design, because it would be faulty. Especially since api calls also result in errors and don’t work offline (with the app successfully loaded). It’s not just the app shell. Plus there is more wrong with the service worker, like the “Uncaught (in promise) TypeError: Cannot read property ‘id’ of undefined” error in my other comment. Anyway, back to the original issue, I don’t think that a refresh vs. opening a fresh tab should be treated differently. As for “having dev tools open” I know it can be an issue. But it behaves the same without dev tools open, static assets and api calls alike. Plus, as far as I know, there should be no issues if you’re on the network tab (or at least it was the case a couple months ago, don’t know if anything changed). When ServiceWorker used to work, the only time it didn’t behave as expected was if I had the Application tab active in dev tools, but worked fine while having any other tab active.

Hi @alxhub - would you be able to give input on whether the ServiceWorkerModule has the “routing” functionality, that was in older versions of the @angular/service-worker package? I know at the time you gave this talk (linked w/ timestamp), the ngsw-manifest.json could be auto-generated with routing based on the AppModule. But now route handling doesn’t seem to be anywhere in the docs, which leads to the 504 errors as in this issue, for non-index, non-dataGroup routes. Would be happy to attempt to work on this, but I’m guessing I’ve missed some discussion about future direction for the service-worker package