question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. ItΒ collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Angular Service Worker breaks HTML forms POST submit

See original GitHub issue

🐞 bug report

Affected Package

The issue is caused by package @angular/service-worker

Is this a regression?

No

Description

We have an hybrid stack with old school PHP pages mixed with an Angular SPA, and the Angular app has a wildcard route redirecting all non-SPA navigations to the legacy PHP stack.

Combined with using the ngsw-bypass query param, the Angular Service Worker works great in most situations. However, it does break HTML forms POST submit, as the Service Worker would then return the app shell (even though req.method was post), causing the SPA to send a new GET request with the ngsw-bypass query param, and breaking the form submission.

To be clear, the entire reason why this is an issue for us is that we have way too many unknown PHP POST endpoints to be able to exclude them all from the navigationUrls regexes (and they often live next to actual SPA routes); the issue does not exist if the POST endpoint is excluded from navigationUrls.

Patching ngsw-worker.js at build time solves our issue, however, considering that POST requests aren’t supported by the Cache API / can’t really be cached by Service Workers, that upload progress events are broken as well, and that (in our case) HTML form POST submits are broken when form action targets match navigationUrls, I wonder it there’s a point for the Angular Service Worker to handle POST requests in the first place.

i.e., is there any downside for the Angular Service Worker to not handle any POST requests at all like we’ve done?

if (req.method === 'POST' || req.headers.has('ngsw-bypass') || /[?&]ngsw-bypass(?:[=&]|$)/i.test(requestUrlObj.search)) {
  return;
}

Looking through the various GitHub issues for related bugs, I feel that this would make real-life Service Worker deployments much easier.

Alternatively, I would argue that the Angular Service Worker should not return the app shell for req.mode === 'navigation' requests if req.method is not GET, in order to stay on the safe side.

πŸ”¬ Minimal Reproduction

I’ve created a small repro at https://github.com/laurentgoudet/angular-service-worker-submit-post-bug: just git checkout, yarn, node server.js, and open http://localhost:8080: the form submit would be broken once the Service Worker has bootstrapped

🌍 Your Environment

Angular Version:


laurent@Laurents-MacBook-Pro webapp [laurent-sw-fix] $ ./node_modules/.bin/ng version

     _                      _                 ____ _     ___
    / \   _ __   __ _ _   _| | __ _ _ __     / ___| |   |_ _|
   / β–³ \ | '_ \ / _` | | | | |/ _` | '__|   | |   | |    | |
  / ___ \| | | | (_| | |_| | | (_| | |      | |___| |___ | |
 /_/   \_\_| |_|\__, |\__,_|_|\__,_|_|       \____|_____|___|
                |___/


Angular CLI: 9.0.5
Node: 12.4.0
OS: darwin x64

Angular: 9.0.5
... animations, cli, common, compiler, compiler-cli, core, forms
... language-service, localize, platform-browser
... platform-browser-dynamic, platform-server, router
... service-worker
Ivy Workspace: Yes

Package                           Version
-----------------------------------------------------------
@angular-devkit/architect         0.900.3
@angular-devkit/build-angular     0.900.3
@angular-devkit/build-optimizer   0.900.3
@angular-devkit/build-webpack     0.900.3
@angular-devkit/core              9.0.3
@angular-devkit/schematics        9.0.5
@angular/cdk                      9.1.1
@angular/material                 9.1.1
@ngtools/webpack                  9.0.3
@nguniversal/builders             9.0.1
@nguniversal/common               9.0.2
@nguniversal/express-engine       9.0.2
@schematics/angular               9.0.5
@schematics/update                0.900.5
rxjs                              6.5.4
typescript                        3.7.5
webpack                           4.41.2

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Comments:7 (3 by maintainers)

github_iconTop GitHub Comments

1reaction
laurentgoudetcommented, Apr 3, 2020

Regarding POST requests, there is value in them going through the SW (even if just to pass through to the network in the end). For example DataGroup uses them to invalidate caches.

Right yeah I had seen that code, and I do agree that it can make sense to flush a cache entry after a mutation, although it mostly applies to data requests (we serialize the Redux store state into local storage and don’t use the SW worker for that).

However, I’d still argue that - until Service Workers get better - all the β€œpotentially broken” features should be opt-in rather than opt-out. In short, that would mean an opposite mechanism to ngsw-bypass, which would require oneself to explicitly opt-in to certain features, e.g.:

  • Pass a ngsw-enable-mutations header to opt-in to POST/PUT requests being handed, i.e. allowing cache invalidation (but breaking upload progress events)
  • Pass a ngsw-enable-range query param to opt-in to Range requests being handled, i.e. allowing media files to be accessed offline (but breaking seeking)
  • Probably something similar for HTTP Basic Auth, as I just realized that it was broken as well.

My point is that it’s much easier to add these extra request headers / query params incrementally in a brand new app (with HTTP interceptors & the like), when ones needs to, compared to the current state of the Angular Service Worker (by default) breaking a lot of different features web sites have relived on for a long time.

It would provide a better & safer developer experience, while still allowing advanced use cases when needed, the longer term goal being to scrap them when Fetch is where it needs to be basically.

I do agree, though, that it doesn’t make much sense for the SW to return index.html (aka the app shell) for non-GET requests. I.e. we could add an extra check for req.method === 'GET' here.

Would you, by any chance, be interested in submitting a pull request, @laurentgoudet?

Yep I’ll try to look into that next week as it’s a different issue to the broader discussion.

I try to understand this issue. Can anyone tell me where I am wrong? I’ve cloned the author’s repo and started the app. The displayed form was sent with no redirects to index.html.

Check that the SW has been properly activated, e.g. Service Workers are disabled in Firefox Private browsing for instance.

0reactions
angular-automatic-lock-bot[bot]commented, Oct 7, 2022

This issue has been automatically locked due to inactivity. Please file a new issue if you are encountering a similar or related problem.

Read more about our automatic conversation locking policy.

This action has been performed automatically by a bot.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Service worker communication - Angular
A user opens the application for the first time and the service worker caches the latest version of the application. Assume the application's...
Read more >
Angular Service Worker with POST request - Stack Overflow
It's a simple GET service. The second one isn't. It's a POST service with a form data sent as payload. Any idea of...
Read more >
Angular Service Worker - Step-By-Step Guide
In this post, we will cover the following topics: Step 1 - Scaffolding an Angular PWA Application using the Angular CLI; Step 2...
Read more >
Angular Service Worker Tutorial - YouTube
Learn how to add a service worker to your Angular ( Angular 2+) app to make it available offline. Service workers can be...
Read more >
Read HTML Form Data Using GET and POST Method in Node.js
Then we'll write the body section. The following code will enable user to add a new employee to the database. <body> <header> <h1>Employee...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found