Web 技术研究所

我一直坚信着,Web 将会成为未来应用程序的主流

HTTP 缓存在程序上的控制

  之前的文章曾提过关于进入页面时一瞬间的白屏的问题。这是因为大多数网页都是通过入口的 html 文件来管理版本,这个文件不会设置头缓存,即使缓存也只是得到个 304 状态码。所以每次总是会请求服务器,这就消耗了几百毫秒的时间,在这其间是白屏的。
  虽然对这个入口文件设置头缓存就可以解决这个问题,但其中也有一些问题。如果这个入口文件都缓存了,那么这个入口文件如何在客户端更新呢?或者换一种问法就是,如何在前端通过程序来刷新 HTTP 缓存?也许这个需求听起来很诡异,但这确实是可以做到的。
  还记得 Vary 这个响应头么?当 Vary 指定的头改变时缓存就会更新。所以上面的需求就可以用 Vary 指定一个头字段,然后每次需要更新缓存时修改这个头字段,这样缓存就可以更新。下面是代码
<?php
echo rand();
header('Cache-Control: max-age=86400');
header('Vary: x-random');
?>
<hr/>
<button id="refreshButton">刷新</button>
<hr/>
<button href="JavaScript:" id="cleanButton">清缓存</button>
<script>
refreshButton.onclick = function() {
  location.href = location.href;
}
cleanButton.onclick = function() {
  var xhr = new XMLHttpRequest();
  xhr.open('HEAD', location.href);
  xhr.setRequestHeader('x-random', Math.random());
  xhr.onload = function() {
    console.log(xhr.responseText);
  };
  xhr.send();
};
</script>
  这个例子中点击页面上的「刷新」是不会向服务器发起请求的(但点击浏览器的刷新会),所以用户第二个进入页面不会有白屏的问题。如果程序需要让页面更新,那就发一个带 Vary 中包含字段的请求,这样本地的缓存就会失效,此后再次点击页面上的「刷新」将会向服务器发起请求。
  上面这个做法算比较麻烦的,其实也有简单粗暴的办法。因为点击浏览器的刷新会让当前页面跳过强缓存,所以只要 location.reload() 即可更新页面。但是这个简单粗暴的做法是需要直接刷新当前页面的,这可能给用户带来不好的体验。
网名:
54.145.94.*
电子邮箱:
仅用于接收通知
提交 悄悄的告诉你,Ctrl+Enter 可以提交哦
神奇海螺
[查看全部主题]
各类Web技术问题讨论区
发起新主题
本模块采用即时聊天邮件通知的模式
让钛合金F5成为历史吧!
次碳酸钴的技术博客,文章原创,转载请保留原文链接 ^_^