强制浏览器页面不缓存

我想出两种方案,

1、服务器端返回文件的时候,设置响应头,

cache-control:no-cache

貌似是这样,告诉浏览器不要缓存;

2、前端控制,核心是,如何区分代码里修改 url 导致的刷新和用户的刷新,代码:

<script>
    let presentTime = (new Date()).getTime(),
        hrefWithoutSearch = location.protocol + '//' + location.host + location.pathname;

    if (localStorage.getItem('previousHref') === null) {
        localStorage.setItem('previousHref', hrefWithoutSearch + "?v=" + presentTime);
        localStorage.setItem('previousAccessTime', presentTime);
        location.href = hrefWithoutSearch + "?v=" + presentTime;
    } else {
        let interval = presentTime - parseInt(localStorage.getItem('previousAccessTime'), 10);
        if (interval > 2000) {
            localStorage.setItem('previousAccessTime', presentTime);
            location.href = hrefWithoutSearch + "?v=" + presentTime;
        }
    }
    </script>

原理:

  1. 代码修改 url 的刷新,不能继续刷新,否则陷入死循环;
  2. 用户的刷新要修改 url,返回新的页面;

所以,onbeforeunload,onunload 都无法来区分,我想到的可以区分的就是,用户的操作

  1. 键盘事件:F5,CTRL+R,地址栏回车,地址栏旁边的刷新按钮
  2. 鼠标事件: 右键刷新

我觉得比较困难,尤其是地址栏回车按钮和地址栏旁的刷新;所以想了另外一个妥协的办法:

页面每次加载,都去 localStorage 里获取上次加载的时间 previousAccessTime,和当前时间一减,得出 interval ,假设跟 3秒 比较;

  1. 3秒外,认为是用户刷新的,在用户刷新导致页面重新加载原来的 url 时,更新 previousAccessTime ,修改 url,导致重新加载了一个新的页面,这个时候的 时间-previousAccessTime 通常小于 3秒,所以适用下一条;
  2. 3秒内,就判断是 代码修改 url 导致的,所以不再去修改 url,避免了循环;
  3. 如果网速慢,导致了修改 url 重新加载的时间超过了3秒,那会重复,导致循环;
  4. 如果把时间改成譬如 10 秒,减少循环的可能,那么用户在 10秒内的刷新,就不会刷新。

后两点是缺点,当然可以通过其他方式去优化,比如,

  1. 调整这个 interval
  2. 把这个脚本放在最前面执行,减小网速慢的影响;

参考:

https://segmentfault.com/q/1010000013079401

posted @ 2018-02-01 20:59  xianshenglu  阅读(1918)  评论(0编辑  收藏  举报