fix(service-worker): only consider GET requests as navigation requests (#47263)

Previously, the criteria for determining if a request was a
[navigation request][1] did not account for the request method. This
incorrectly identified HTML form submit POST requests as navigation
requests and served `index.html` instead of passing them through to the
server, thus breaking the form submission.

This commit fixes this by ensuring that only GET requests are considered
navigation requests.

> **Note**
> HTML forms with their method set to `GET` will still be affected by
> the issue. This is not a big concern, because using `GET` for form
> submission is quite uncommon and generally discouraged (due to
> limitations and security considerations).

[1]: https://angular.io/guide/service-worker-config#handling-navigation-requests

Fixes #36368

PR Close #47263
This commit is contained in:
George Kalpakas
2022-08-25 22:08:35 +03:00
committed by Andrew Kushnir
parent 56304d6b95
commit 28d33505fd
3 changed files with 11 additions and 2 deletions
@@ -376,6 +376,7 @@ This optional section enables you to specify a custom list of URLs that will be
The ServiceWorker redirects navigation requests that don't match any `asset` or `data` group to the specified [index file](#index-file).
A request is considered to be a navigation request if:
* Its [method](https://developer.mozilla.org/docs/Web/API/Request/method) is `GET`
* Its [mode](https://developer.mozilla.org/docs/Web/API/Request/mode) is `navigation`
* It accepts a `text/html` response as determined by the value of the `Accept` header
* Its URL matches the following criteria:
@@ -203,10 +203,10 @@ export class AppVersion implements UpdateSource {
/**
* Determine whether the request is a navigation request.
* Takes into account: Request mode, `Accept` header, `navigationUrls` patterns.
* Takes into account: Request method and mode, `Accept` header, `navigationUrls` patterns.
*/
isNavigationRequest(req: Request): boolean {
if (req.mode !== 'navigate') {
if (req.method !== 'GET' || req.mode !== 'navigate') {
return false;
}
@@ -1704,6 +1704,14 @@ describe('Driver', () => {
server.assertNoOtherRequests();
});
it('does not redirect to index on a non-GET request', async () => {
expect(await navRequest('/baz', {method: 'POST'})).toBeNull();
server.assertSawRequestFor('/baz');
expect(await navRequest('/qux', {method: 'PUT'})).toBeNull();
server.assertSawRequestFor('/qux');
});
it('does not redirect to index on a non-navigation request', async () => {
expect(await navRequest('/baz', {mode: undefined})).toBeNull();
server.assertSawRequestFor('/baz');