history.pushState & DOM Exception 18

You might have seen this error thrown in your production logs on several occasions leaving you wondering « Wat ».

SecurityError: DOM Exception 18 is thrown by Safari (iOS and OSX) from the moment pushState is called 100 times. This is related to an exploit used in crashsafari.com which, you can probably guess, used to crash Safari (and other Webkit browsers).

According to Apple, this is « by design », but judging from this revision, the restriction was softened in Webkit on March 25 2016.

You can easily reproduce this issue by running in your Safari console:

1
for(var i=0; i < 100; i++){history.pushState({},"","")};

Any subsequent pushState/replaceState call will throw this error.

The good news is that, appart from not updating the browser URL anymore, this issue doesn’t affect your users. But a bug is a bug…

Ember.onerror to the rescue

Until this is merged (if it is ever merged), you can work around the issue in Ember.js by refreshing the browser window, thus reseting the pushState limitation :

1
2
3
4
5
6
7
8
Ember.onerror = function(error) { if (error.message.match(/DOM Exception 18/)) { return Ember.run.later(function(){ window.location.reload(); /* or ignore... */ }); } };