Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular service worker with @angular/pwa package showing `HTTP error 504` when offline

I am working on an angular PWA application. So I added an npm package by ng add @angular/pwa. It is added successfully with no errors.

The generated Manifest is working fine. But I am facing issues with the service worker. When the application goes online it stores all the caches (see attachment) but whenever the application goes offline, instead of serving the request from the service worker it shows the error - HTTP ERROR 504

Here is my ngsw-config.json -

   {
    "index": "/index.html",
    "assetGroups": [
      {
        "name": "app",
        "installMode": "prefetch",
        "resources": {
          "files": ["assets/images/favicon.ico", "/index.html", "/*.css", "/*.js"]
        }
      },
      {
        "name": "assets",
        "installMode": "lazy",
        "updateMode": "prefetch",
        "resources": {
          "files": [
            "/assets/**",
            "/*.(eot|svg|cur|jpg|png|webp|gif|otf|ttf|woff|woff2|ani)"
          ]
        }
      }
    ]
  }

Any help would be appreciable...

enter image description here

enter image description here

like image 610
Alok Mali Avatar asked Dec 04 '22 17:12

Alok Mali


1 Answers

Why error 504?

The 504 error doesn't come from your server, it comes from the service worker that is acting like a proxy.

Every HTTP request you make in your PWA passes through the service worker (SW), and two things may occur:

  • If the requested resource is on the SW cache, then it returns the content of the cache
  • If the requested resource is not on the SW cache, then the SW performs the request to the server

So if you are offline and the resource is not on the SW cache, then the SW will try to make the request to the server, but, as you are offline, that request will fail and the SW will return a 504 error. You can see that this is actually happening in the last image you posted: the http response at the top is the one you got from the SW with error 504 and the request below (see wheel icon at the left) is the one the SW performed to the server and failed.

Why cache mismatch?

Now, you may be wondering, why the SW doesn't find the resource in its cache?

Well, the Angular service worker is a great tool but it is very sensitive in a way that a minimum change will make it not work. The first thing you need to know is the caching mechanism it uses. Basically, when you build your Angular app, all the generated files have an associated hash that is computed with the content of each file (check the generated ngsw.json file). When your app is running, the SW compares this hash (computed at compilation time) with the hash of the requested resource (computed at runtime).

Many users report problems with this mechanism and some common reasons are:

  • Intermediate services (such as Cloudflare) that minify/uglify JS, CSS and HTML files
  • Automated scripts on a deployment pipeline that modify some files
  • FTP clients (such as FileZilla) that transfer files on text mode instead of binary mode (changing their encoding, line endings, etc)

All these produce changes on the file content and thus the SW will compute a different hash to the one computed on compilation time. This will cause a cache mismatch and your app won't work offline (you will get http 504 response).

Aditional information

Note that some users report that the app works offline sometimes or in some specific browsers. A possible explanation is that a browser-level cache mechanism is acting in these cases, instead of the SW cache itself.

To debug the Angular SW further, you can check its self-hosted debug page at /ngsw/state.

I recommend you to read the documentation of the Angular service worker and this discussion.

like image 140
Martín De la Fuente Avatar answered Jan 22 '23 07:01

Martín De la Fuente