简体   繁体   中英

Enforcing reload of remote index.html in an Angular progressive web app

I have an Angular 8 web app that uses Angular PWA and service worker.

The customer wants to add maintenance mode to the system to be able to cut off the users and display a simple HTML page with the downtime information.

On the server side it works simply by returning 503 and a maintenance mode HTML page. While the page is based on a template, I cannot include it in my SPA webapp because customer's admins might want to adjust it for the situation (eg to explain how long the maintenance will last).

The question boils down to this: how to enforce the web browser to show the remote index.html with maintenance text instead of the cached index.html? How is it usually done in a typical Angular SPA application, that was created using a Visual Studio Angular SPA template?

The longer explanations:

The problem is the client side. Since this is a PWA that mostly communicates with the back-end through API, there are three potential points when the user might receive 503 response:

  • when loading the site for the very first time. This is not a problem, users get the maintenance page immediately.

  • when the site has been already loaded and the user is doing a normal page refresh (not full reload). This is a problem because the cached SPA root index.html is returned by the service worker instead of the modified index.html on the server. Fortunately, my SPA is doing some web requests immediately after launching, so I can catch 503 there, and thus it all boils down to the third point:

  • the most often 503 status will be caught while the user is working on some task and the app calls my server API. I have a global error handler (based on ErrorHandler) added to my HTTP service calls in my Angular code, so I can catch 503 response. But what should I do next? How do I force full reload of website, ignoring the service worker cache to enforce reloading of the remote index.html page?

What have I already attempted:

As a quick&dirty workaround, I have added the following code in my error handler:

    if (error.status === 503) {
        // the server should have offline page. If not, the request will lead to 404.
        document.location.href = "offline.html?_=" + Math.floor(Math.random() * 1000000000);
    }

This assumes that the remote server has offline.html file instead of newly modified index.html. The problem with this approach is that the user won't be able to simply continue refreshing the page because they'll get the offline.html and finally 404 instead of the revived index.html after the server has been restored from the maintenance mode. It would be nicer to force the maintenance text in the same index.html, but unfortunately, the browser keeps displaying the cached SPA index.html instead.

In case if someone else stumbles upon the same question: I ended up with such a bit ugly solution:

    else if (error.status === 503) {
        // we assume the server has sent us entire offline html page contents
        // and we rewrite current page with it entirely
        document.open();
        // error is the response body
        document.write(error.error);
        document.close();
    }

This way:

  • if the user loads the website for the first time, they will receive the server's 503 response immediately
  • if the user loads the website from browser's cache, the website will receive 503 sometime later, but, most likely, very soon because of some immediate API requests, and then we come to the last:
  • if the user receives 503 status when calling API, the entire visible document will get replaced with the text from the server.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM