Firefox does not act on history.pushState calls during a (Service Worker) navigation event
Categories
(Core :: DOM: Navigation, defect, P3)
Tracking
()
People
(Reporter: cm.jasonyoung, Unassigned, NeedInfo)
Details
Attachments
(2 files)
User Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.114 Safari/537.36
Steps to reproduce:
We have a service worker that is intercepting navigation events. For certain ones, we will return a 204 response and use postMessage to send the tab different data to render. In order to update the url and create a history entry, we use history.pushState.
Actual results:
When history.pushState is called while the browser is waiting for the navigation event to end (after the fetch event in the service worker but before the 204 response), the url will change but the history entry will not be created. If history.pushState is called via a setTimeout, both the url and the history entry will be updated.
Expected results:
In Chrome/Edge and Safari, calling history.pushState during a navigation event will update both the history entry and the url. We're not sure if this is the intended behavior for Firefox or if it is a bug. We haven't found any documentation on this so I'm submitting it as a bug report given the difference in behavior between browsers.
Comment 1•3 years ago
|
||
The Bugbug bot thinks this bug should belong to the 'Core::DOM: Navigation' component, and is moving the bug to that component. Please revert this change in case you think the bot is wrong.
Comment 2•3 years ago
|
||
cm.jasonyoung, thank you for the report. Would you be able to submit a testcase for this behavior which can help us to quickly identify and fix the issue?
Reporter | ||
Comment 3•3 years ago
|
||
Hi Neha, sorry for the delay. I've attached the requested test case. In order to use it, do the following:
- Unzip the file
- Open a terminal in the folder
- Run
npm i
- Run
npm start
- Go to http://127.0.0.1:8080/page1 in Chrome or Safari
- Click on the
Page 1
andPage 2
links a few times - Verify you see the body changing and history entries being created
- Go to http://127.0.0.1:8080/page1 in Firefox
- Click on the
Page 1
andPage 2
links a few times - Verify you see the body changing but no history entries being created
- Modify the history call in page1.html and page2.html to be
setTimeout(() => history.pushState({}, document.title, url), 100);
- Unregister the service worker and refresh the page
- Click on the
Page 1
andPage 2
links a few times - Verify you see the body changing and history entries being created
I believe this shows both Firefox's behavior is different from Chrome and Safari and that history.pushState does work after the navigation event has been processed. Please let me know if you need any more information.
Comment 4•3 years ago
|
||
Thanks for the test case! That's a big help.
We need to determine whether the HTML standard specifies how to handle history.pushState calls during a navigation event and whether this problem happens during a regular navigation without a Service Worker.
Reporter | ||
Comment 5•3 years ago
|
||
Hi Chris,
I've attached another test case, showing the different behavior for Firefox without a service worker. To use it, please do the following:
- Unzip the file
- Open a terminal in the folder
- Run
npm i
- Run
npm start
- Go to http://localhost:8080/page1 in Chrome or Safari
- Click on the
Page 1
andPage 2
links - Verify you see 2 history entries created for each page navigation
- Go to http://localhost:8080/page1 in Firefox
- Click on the
Page 1
andPage 2
links - Verify you see only 1 history entry created for each page navigation.
Note that the response is always delayed by 1 second and the push state is delayed by 100 ms, which means it is always called after the navigation has started but before the response is received by the browser.
Looking at https://html.spec.whatwg.org/#shared-history-push/replace-state-steps, the main restrictions seems to be around preventing abuse by setting rate-limits/maximum history entries/rejecting too-large states. Since the tab is active and the pushState is being called because of a user action, I believe this should be allowed.
Reporter | ||
Comment 6•3 years ago
|
||
Hi, I was wondering what the next step for this is. Do you need any more information from me or we waiting for someone to have time to look into this?
Comment 7•3 years ago
|
||
(In reply to Jason Young from comment #6)
Hi, I was wondering what the next step for this is. Do you need any more information from me or we waiting for someone to have time to look into this?
Hi Jason, I think we are just waiting for a Mozilla engineer to investigate. Unfortunately, I don't have an ETA.
Reporter | ||
Comment 8•3 years ago
|
||
(In reply to Chris Peterson [:cpeterson] from comment #7)
(In reply to Jason Young from comment #6)
Hi, I was wondering what the next step for this is. Do you need any more information from me or we waiting for someone to have time to look into this?
Hi Jason, I think we are just waiting for a Mozilla engineer to investigate. Unfortunately, I don't have an ETA.
Ok sounds good. I just wanted to make sure I wasn't holding this up. Thanks for the update!
Comment 9•2 months ago
|
||
I don't know what navigation event is this talking. Asuth, perhaps you do?
Description
•