How to cache page loaded via ajax with pushState URL so that reloading page from server can be avoided? For instance,
page 1: /foo.html. click button, send ajax request, get response and update the page. History pushState as a new page /bar.html.
history.pushState({}, '','/bar.html');
At this point, we like the browser to cache the current page as /bar.html.
window.onpopstate = function(event) {
// browser is not loading page automatically for back/forward
if (event.state)
location.reload();
};
When clicking back/forward button, the /bar.html should be loaded from browser cache. But it is loaded from server again. How to achieve this? that is, let the ajax updated page treated as regular GET /bar.html, and cached by browser. how?
Thanks for any clue. Dave
How to cache page loaded via ajax with pushState URL so that reloading page from server can be avoided? For instance,
page 1: /foo.html. click button, send ajax request, get response and update the page. History pushState as a new page /bar.html.
history.pushState({}, '','/bar.html');
At this point, we like the browser to cache the current page as /bar.html.
window.onpopstate = function(event) {
// browser is not loading page automatically for back/forward
if (event.state)
location.reload();
};
When clicking back/forward button, the /bar.html should be loaded from browser cache. But it is loaded from server again. How to achieve this? that is, let the ajax updated page treated as regular GET /bar.html, and cached by browser. how?
Thanks for any clue. Dave
Share Improve this question edited May 18, 2014 at 6:17 Dave asked May 18, 2014 at 3:05 DaveDave 5071 gold badge6 silver badges19 bronze badges 16- “How to achieve this?” – the same way you would achieve it, were AJAX and pushState not involved at all. – C3roe Commented May 18, 2014 at 3:06
- how to tell browser to cache it as new URL? Thanks. – Dave Commented May 18, 2014 at 3:38
- 1 You simply make your AJAX request again when the user navigates to that history entry again – and if you have implemented proper caching, then the browser will take the data from cache instead of requesting it again. – C3roe Commented May 18, 2014 at 3:43
- set response header Cache-Control: max-age=86400. Chrome/FireFox browser does not cache it. onpopstate: location.reload() always requests the page again from server. – Dave Commented May 18, 2014 at 5:10
- 1 When using the History API, you have to handle what content gets displayed when the user navigates back and forth, that is correct. But nobody is forcing you to do that by reloading the page … You used AJAX already to fetch the content and then put it into the DOM, right? So what is keeping you from doing exactly that again (and thereby making use of the browser’s cache, when it will realize, “hey, I have already loaded that content once before already, so I don’t have to make a new HTTP request here, but I can answer that AJAX request by taking the data out of my cache”) …? – C3roe Commented May 18, 2014 at 5:53
1 Answer
Reset to default 5If you enable http caching adding the appropriate headers in your responses (Cache-Control, Expires, Last-Modified etc.) then these responses will be stored in cache. There is not one cache. There is the server's cache and downstream caches (ISP, proxies, browser). One of these is the browser's cache.
Suppose that you cache the responses. Have in mind that an http response will be cached no matter its content-type (html, json etc.) So, you load page A, then click on a link that updates the page with ajax and the url with the history api. This is page B. Then you visit page C. The responses A, B and C are stored in browser's cache. But if you go back to page B the browser doesn't automatically load it since you have used the History api for that url. It just updates the url and fires a popstate event.
- One approach is to listen to popstate and manually make the same ajax call. Since the response B is already stored in browser's cache, it will be retrieved from there (if it has not been changed in the server).
Another approach would be to store the data retrieved from ajax in an object called state and associate it with the pushed url:
state = { your_key: your_value } history.pushState(state, title, url)
Then on back button catch the popstate event, get its associated state object, access your data and modify the page.
$(window).on('popstate', function(event) { var state = event.originalEvent.state; if (state) { // use it to modify the page }else{ // ajax call to get the data } });
In this case if state exists you don't actually use the browser's cache to retrieve the response.
Have in mind that the state object is stored in client's disk and is of limited size. Thus it is better to store in the state object a reference to the data (for example an id) and store the data itself in memory. This assumes though that you have a Signle Page Application all pages of which are loaded with ajax. (A normal page loading will clear your client's memory)