Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is History API consistent across modern browsers?

History API is now supported in every popular browser. It seems there's no need for hash fallbacks, _escaped_fragment_ tricks or other workarounds anymore. Cool libraries from 2013 like History.js seem useless now. But there are some things where I'm not sure - for example title handling seems tricky beacuse apparently title argument in pushState doesn't do anything.

My question is, can I actually rely on the History API to behave consistently across browsers, or do I still need some browser-specific code? This also means: do I need integration tests running in different browsers to test my code then? And if there are inconsistencies, what are they? (Note I'm interested only in modern browsers, so no IE<11).

Maybe someone who implemented routing for a big SPA could share their experience?

like image 747
mik01aj Avatar asked Aug 10 '16 17:08

mik01aj


2 Answers

Note: This is not a complete answer so I'm not expecting a bounty but it still answers some concerns so I decided to put it as an answer

There are still some differences as with most APIs (you won't believe how inconsistent classList is between browsers); the question is mostly how severe they are.

pushState is most commonly used in SPAs and they seem to ignore the object parameter and mostly handle the URL. This means bugs related to state object handling may be less "visible" to the general public.

The only issue I've recently found that influenced what I was doing is that in IE & Edge (even 14) history.state is a getter so it gets a fresh object instance on every access. This means you can't cache the state object and compare it to history.state to see if a new one was pushed. Here's the bug report: https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/944050/

Also, note that no browser supports setting title via pushState and no one ever will, it's too late. If a browser started supporting that, pushState-using sites would suddenly clear all titles in browser history because code is passing empty strings there. You just have to accept that the second parameter is useless.

like image 108
mgol Avatar answered Nov 15 '22 13:11

mgol


Actually you can see all the supported browsers by history lib: https://github.com/browserstate/history.js/#browsers-tested-and-working-in

And buglist solved by this lib, from the same page:

  • HTML5 Browsers
    • Chrome 8 sometimes does not contain the correct state data when traversing back to the initial state
    • Safari 5, Safari iOS 4 and Firefox 3 and 4 do not fire the onhashchange event when the page is loaded with a hash
    • Safari 5 and Safari iOS 4 do not fire the onpopstate event when the hash has changed unlike the other browsers
    • Safari 5 and Safari iOS 4 fail to return to the correct state once a hash is replaced by a replaceState call / bug report
    • Safari 5 and Safari iOS 4 sometimes fail to apply the state change under busy conditions / bug report
    • Google Chrome 8,9,10 and Firefox 4 prior to the RC will always fire onpopstate once the page has loaded / change recommendation
    • Safari iOS 4.0, 4.1, 4.2 have a working HTML5 History API - although the actual back buttons of the browsers do not work, therefore we treat them as HTML4 browsers
    • None of the HTML5 browsers actually utilise the title argument to the pushState and replaceState calls
  • HTML4 Browsers
    • Old browsers like MSIE 6,7 and Firefox 2 do not have a onhashchange event
    • MSIE 6 and 7 sometimes do not apply a hash even it was told to (requiring a second call to the apply function)
    • Non-Opera HTML4 browsers sometimes do not apply the hash when the hash is not urlencoded
  • All Browsers
    • State data and titles do not persist once the site is left and then returned (includes page refreshes)
    • State titles are never applied to the document.title

This might tell you something about existing differences.

like image 29
Artur Szott Avatar answered Nov 15 '22 12:11

Artur Szott