最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - History pushState and cache page - Stack Overflow

programmeradmin3浏览0评论

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
 |  Show 11 more ments

1 Answer 1

Reset to default 5

If 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.

  1. 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).
  2. 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)

发布评论

评论列表(0)

  1. 暂无评论