Manipulating window.history affects favicon on IE11

998 views Asked by At

Here's the scenario: The site has a favicon already cached (/favicon.ico file) and I want to change it. It can be easily achieved (by adding a querystring to favicon's path: favicon.ico?v2). But, any state change (by calling window.history.pushState() or window.history.replaceState()) changes the favicon to the old one.

It looks like IE11 is taking favicon.ico from BASE directory which is unfortunately cached (favicon.ico?v2 is treated as a different entity in IE11's cache).

It's worth mentioning that the problem is not occurring when manipulating location.hash. So changing state from:

http://x.com

to:

http://x.com/#id=5

has no affect on the favicon. But changing state to:

http://x.com/?id=5

switches the favicon to the old one (if it's cached) or default from IE11. As soon as I do a browser refresh the new favicon is shown.

This was already reported as a bug on IE11, but Microsoft decided to leave it. I found two related questions: using history.pushState in Firefox make my favicon disappear & history.pushState in Chrome make favicon request but none provides a solution to my problem.

I've also tried to update the favicon's reference after changing the state (by updating link href attribute) - it helped on Edge but not on IE11. the browser is actually sending a new favicon request, but it still shows the old one.

I'm looking for a way of keeping the favicon after changing the state. The alternative solution can be to programmatically forcing IE11 to reload favicon.ico file (let's assume that Expires header was not set).

1

There are 1 answers

0
Felix Price On

There is a solution, but it's quite hacky.

The Problem is, that IE caches the favicons seperately and they will only be loaded, if the entire page is. The pushState just checks the existing cache and will only show favicons of pages that have been loaded before. If pushState has not been used you can change the favicon with JavaScript, afterwards, you can't.

The favicon cache however is updated live, so you can do the following:

  • Set up a hidden iframe on your page.
  • Before calling pushState, load the page you need with an additional hash (e.g #onlyFavicon) in the iframe (make sure to use replace otherwise the ifarem will interfere with your history).
  • Have your server - or a javaScript - check for your hash on pageload and serve an empty page with just the favicon.
  • Once the iframe has loaded, your favicon cache is updated with the new favicon (add an onLoad eventlistener to the iframe to know when) No Need to wait, the favicon gets updated automtically once the iframe has loaded.
  • If you call pushState now, the favicon will be displayed correctly

I know it's hacky and late, but i hope it helps anyone who stumbles over this problem as well.