美文网首页设计师要了解的技术让前端飞@IT·互联网
微信自带浏览器物理返回不刷新问题

微信自带浏览器物理返回不刷新问题

作者: IC男奋斗史 | 来源:发表于2017-07-23 13:10 被阅读1791次
    问题描述与需求
    1. 非单页面应用;
    2. 在页面A,通过get方式进入页面B之后再回到页面A,这个时候微信iOS版页面不刷新,安卓版微信刷新页面 ---> 所有物理返回都必须强制刷新重新进入页面;
    3. 在页面A,通过get方式进入页面B之后再回到页面A,这个时候所有版本的微信在页面A上数据没有更新 ---> 需要更新数据;

    分析与提出问题

    问题一. 通过后端同事查看访问日志发现,所有版本上的微信页面返回数据不更新是因为发生Ajax缓存。最后自己在Chrome 上查看发现:

    屏幕快照 2017-07-23 上午10.53.19.png
    disk cache: 原始资源被存储在本地磁盘上

    问题二. iOS版微信自带浏览器物理返回没有重新请求页面的原因:Page Cache/Back-Forward Cache

    解释:
    1. Firefox称之为bfcache,webkit称之为Page Cache,Opera称之为Fast History Navigation。这里的cache不是HTTP规范里的cache,不是disk cache中的cache(原始资源被存储在本地磁盘上),也不是传统的memory cache中的cache(Webkit把解码后的资源保存在内存中以在多个网页之间共享)。
    2. 因为不是HTTP中的cache,所以在header中设置no-storeno-cache是行不通的;
    3. 具体解释见《JavaScript高级程序设计》第393页;

    解决问题思路
    问题一:
    1. 在发起Ajax请求时,在请求链接上加时间戳作为参数,以欺骗浏览器,使得每次请求数据的链接都不一样,这样Ajax就不会缓存了(参考第1个文档,具体见下图);
      屏幕快照 2017-07-23 下午1.16.23.png
    问题二尝试方法:
    1. Web缓存:在HTML页面中的<meta>标签里,no-storeno-cache首部可以禁止缓存对响应进行复制(见参考文档第2条第1个回答)如:
    <meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate" />
    错误原因:
        1. <meta http-equiv>标签在HTML5中失效;
        2. HTTP response header优先级高于HTML meta tag;
        3. HTML meta tag只在查看本地文件文件时用到;
    
    1. 页面链接加时间戳(见参考文档第1个)
    history.replaceState({}, "todo", location.pathname+'?time='+(+new Date()));
    虽然每次进入这个页面的时间戳都不一样,但是还是不行。
    错误原因:未找到
    
    1. 监听返回操作并刷新页面(见参考文档第3个):
    componentDidMount() {
          window.addEventListener('hashchange', () => {
            window.history.replaceState('hasHash', '', '');
          }, false);
          window.addEventListener('popstate', () => {
            window.location.reload();
          }, false);
        }
    componentWillUnmount() {
          window.removeEventListener('hashchange');
          window.removeEventListener('popstate');
        }
    错误原因:未找到
    
    1. 搞清楚是Page Cache/BF Cache的原因之后,监听pageshow事件
      注意:这个方法无法解决返回时发生的Ajax缓存,因为Ajax缓存是disk cache
    window.onpageshow = function(event) {
        if (event.persisted) {
          window.location.reload()
        }
      };
    

    Bingo!

    1. 根据《JavaScript高级程序设计》第394页的说明,指定onunload事件不会执行bfcache,那么可以执行以下代码:
    <body onunload="" ></body>
    或者
    window.onunload = function(){};
    但不可行,原因未知。
    

    总结
    1. 搞清楚问题的原因是最重要的,知道了原因就好解决问题了;
    2. 用博客方式记录自己的思路过程是一个不错的方式;
    3. 《JavaScript高级程序设计》是一本神奇的书,需要好好反复研读;

    参考文档

    1. http://blog.csdn.net/u010537398/article/details/52155726
    2. https://stackoverflow.com/questions/49547/how-to-control-web-page-caching-across-all-browsers
    3. https://github.com/luokuning/blogs/issues/3
    4. http://www.cnblogs.com/AeroJin/p/4783408.html
    5. http://blog.csdn.net/wy5761/article/details/21041191
    6. https://juejin.im/entry/58882350b123db16a344c74a

    相关文章

      网友评论

      • Chris:其实。。用点框架就好
        我还在想怎么现在还有人遇到这样问题
        a2d5f8877582:你说的是前端框架?用什么能解决呢
        Chris:@米店的老板娘 也是 不过这个如果要了解 实际上不只微信浏览器也会这样 应该了解的是为什么浏览器会这样处理
        IC男奋斗史:@Chris 基础的知识一定要了解,知其然才能知其所以然。

      本文标题:微信自带浏览器物理返回不刷新问题

      本文链接:https://www.haomeiwen.com/subject/bxqmkxtx.html