Dav*_*ave 5 javascript ajax caching pushstate popstate
如何使用 pushState URL 缓存通过 ajax 加载的页面,以避免从服务器重新加载页面?例如,
第 1 页:/foo.html。单击按钮,发送ajax请求,获取响应并更新页面。历史 pushState 作为一个新页面 /bar.html。
history.pushState({}, '','/bar.html');
Run Code Online (Sandbox Code Playgroud)
此时,我们喜欢浏览器将当前页面缓存为/bar.html。
window.onpopstate = function(event) {
// browser is not loading page automatically for back/forward
if (event.state)
location.reload();
};
Run Code Online (Sandbox Code Playgroud)
单击后退/前进按钮时,应从浏览器缓存中加载 /bar.html。但它再次从服务器加载。如何实现这一目标?也就是让ajax更新的页面作为常规的GET /bar.html处理,并被浏览器缓存。如何?
感谢您提供任何线索。戴夫
如果您启用 http 缓存,在您的响应中添加适当的标头(Cache-Control、Expires、Last-Modified 等),那么这些响应将存储在缓存中。没有一个缓存。有服务器缓存和下游缓存(ISP、代理、浏览器)。其中之一是浏览器的缓存。
假设您缓存了响应。请记住,无论其内容类型(html、json 等)如何,都会缓存 http 响应。因此,您加载页面 A,然后单击使用 ajax 更新页面的链接和使用历史记录 api 更新的 url。这是页面 B。然后您访问页面 C。响应 A、B 和 C 存储在浏览器的缓存中。但是,如果您返回到页面 B,浏览器不会自动加载它,因为您已经为该 url 使用了 History api。它只是更新 url 并触发 popstate 事件。
另一种方法是将从 ajax 检索到的数据存储在一个名为 state 的对象中,并将其与推送的 url 相关联:
state = { your_key: your_value }
history.pushState(state, title, url)
Run Code Online (Sandbox Code Playgroud)
然后在后退按钮上捕获 popstate 事件,获取其关联的状态对象,访问您的数据并修改页面。
$(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
}
});
Run Code Online (Sandbox Code Playgroud)
在这种情况下,如果 state 存在,您实际上并不使用浏览器的缓存来检索响应。
请记住,状态对象存储在客户端的磁盘中并且大小有限。因此,最好在状态对象中存储对数据的引用(例如 id)并将数据本身存储在内存中。这假设您有一个 Signle 页面应用程序,其中所有页面都加载了 ajax。(正常的页面加载会清除您客户的记忆)