Chrome displays ajax response when pressing back button

I've come across a problem that if I use jQuery's Get method to get some content, if I click back, instead of it actually going back one page in the history, it instead shows the content returned by the Ajax query.

Any idea's?

http://www.dameallans.co.uk/preview/allanian-society/news/56/Allanian-test

On the above page, if you use the pagination below the list of comments you will notice when clicking back after changing a page, that it shows the HTML content used to generate the list of comments.

I've noticed it doesn't always do it, but if you click on a different page a few times and click the back button, it simply displays json text within the window instead of the website.

For some reason, this is only affecting Chrome as IE and Firefox work ok.


Make sure your AJAX requests use a different URL from the full HTML documents. Chrome caches the most recent request even if it is just a partial.

https://code.google.com/p/chromium/issues/detail?id=108425


Just in case you are using jQuery with History API (or some library like history.js), you should change $.getJSON to $.ajax with cache set to false:

$.ajax({
    dataType: "json",
    url: url,
    cache: false,
    success: function (json) {...}
});

Actually this is the expected behavior of caching system according to specs and not a chrome issue. The cache only differentiate requests base on URL and request method (get, post, ...), not any of the request headers.

But there is a Vary header to tell browser to consider some headers when checking the cache. For example by adding Vary:X-Requested-With to the server response the browser knows that this response vary if request X-Requested-With header is changed. Or by adding Vary:Content-Type to the server response the browser knows that this response vary if request Content-Type header is changed.

You can add this line to your router for PHP:

header('Vary:X-Requested-With');

And use a middleware in node.js:

app.use(function(req, res) {
    res.header('Vary', 'X-Requested-With');
});

You can also add a random value to the end of the ajax url. This will ignore the previous chrome cache and will request a new version

url = '/?'+Math.random()

Just add the following header to the Response headers :

Vary: Accept