移动端H5页面返回并刷新页面(BFcache)的方法


Posted in Javascript onNovember 06, 2018

项目中的需求:

点击浏览器中的返回按钮,要让页面重新加载资源。因为这部分的资源每次去加载的内容都不一样,如果返回的时候,还是看到原先的内容,那做这个内容块的意义就很小了;而如果用户看完了这部分内容,再返回来的时候,这个地方换成了新的内容,这样就能体现这部分的价值了。

而对于浏览器来说,大部分浏览器的返回是直接使用缓存的,不会执行任何的javascript代码。原因:部分浏览器在后退时不会触发onload事件,?是HTML5世代浏览器新增的特性之一——Back-Forward Cache(简称bfcache)

什么是bfcache?

bfcache,即back-forward cache,可称为“往返缓存”,可以在用户使用浏览器的“后退”和“前进”按钮时加快页面的转换速度。这个缓存不仅保存页面数据,还保存了DOM和JS的状态,实际上是将整个页面都保存在内存里。如果页面位于bfcache中,那么再次打开该页面就不会触发onload事件

pageshow事件

这个事件在用户浏览网页时触发,pageshow 事件类似于 onload 事件,onload 事件在页面第一次加载时触发, pageshow 事件在每次加载页面时触发,即 onload 事件在页面从浏览器缓存中读取时不触发。

pagehide事件

该事件会在用户离开网页时触发。离开网页有多种方式。如点击一个链接,刷新页面,提交表单,关闭浏览器等。pagehide 事件有时可以替代 unload事件,但 unload 事件触发后无法缓存页面。

persisted属性

pageshow事件和pagehide事件的event对象还包含一个名为persisted的布尔值属性。

对于pageshow事件,如果页面是从bfcache中加载的,则这个属性的值为true;否则,这个属性的值为false。

对于pagehide事件,如果页面在卸载之后被保存在bfcache中,则这个属性的值为true;否则,这个属性的值为false。

不同的浏览器在对当前窗口‘打开'历史记录中的前一个页面的表现上并不统一,这和浏览器的实现以及页面本身的设置有关系。

解决方案:

javascript监听pageshow事件阻止页面进入bfcache

window.addEventListener('pageshow', function (e) {
if (e.persisted) {
window.location.reload()
}
})

在uc和微信中测试通过,但是在某些安卓手机自带的浏览器中无效。

javascript监听pagehide事件阻止页面进入bfcache

window.addEventListener('pagehide', function (e) {
 var dom = document.body;
 dom.children.remove();
 setTimeout(function () {
  dom.appendChild("<script type='text/javascript'>window.location.reload();<\/script>");
 });
});

设置meta标签,清除页面缓存

<meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate" />
<meta http-equiv="Pragma" content="no-cache" />
<meta http-equiv="Expires" content="0" />

Cache-Control指定请求和响应遵循的缓存机制。在请求消息或响应消息中设置Cache-Control并不会修改另一个消息处理过程中的缓存处理过程。请求时的缓存指令包括no-cache、no-store、max-age、max-stale、min-fresh、only-if-cached,响应消息中的指令包括public、private、no-cache、no-store、no-transform、must-revalidate、proxy-revalidate、max-age。各个消息中的指令含义如下

  • Public指示响应可被任何缓存区缓存
  • Private指示对于单个用户的整个或部分响应消息,不能被共享缓存处理。这允许服务器仅仅描述当用户的部分响应消息,此响应消息对于其他用户的请求无效
  • no-cache指示请求或响应消息不能缓存
  • no-store用于防止重要的信息被无意的发布。在请求消息中发送将使得请求和响应消息都不使用缓存。
  • max-age指示客户机可以接收生存期不大于指定时间(以秒为单位)的响应
  • min-fresh指示客户机可以接收响应时间小于当前时间加上指定时间的响应
  • max-stale指示客户机可以接收超出超时期间的响应消息。如果指定max-stale消息的值,那么客户机可以接收超出超时期指定值之内的响应消息。

注:有些情况下设置清除缓存也没有起到作用,我自己做的这个h5页面就没有起到效果。具体情况还是要具体分析。

我遇到的情况:

<div class="content">
<iframe id="iframe" src="https://cpu.baidu.com/xx/xx/xxx" frameborder="no" scrolling="no"></iframe>
</div>

这个iframe中的地址每次刷新页面都会有不同的内容推送给用户。进入iframe中的内容之后,按返回按钮返回来想进行页面自动刷新,为的就是让用户看到新的内容。

做法:

使用pageshow进行整个页面刷新

window.addEventListener('pageshow', function (e) {
if (e.persisted) {
window.location.reload()
}
})

这样可以实现。

后面又觉得不妥,没有因为这个小部分而进行整个页面刷新,想到了另一种思路:因为这个iframe中的内容是动态的,可以对其进行定时器设置,如下:

let iframe = document.getElementById('iframe')
setInterval(() => {
iframe.setAttribute("src", "https://cpu.baidu.com/xx/xx/xx");
},15000)

这样也可以实现自己的功能。

最后可以结合一下:

let iframe = document.getElementById('iframe')
window.addEventListener('pageshow', function (e) {
 if (e.persisted) {
  iframe.setAttribute("src", "https://cpu.baidu.com/xx/xx/xx");
 }
})

这样做也有好处,可以避免使用定时器,对网页的性能也是比较好。但是这个方法在返回的时候,可以看到iframe里面内容的重新加载,会有一个时间间隙。

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对三水点靠木的支持。

Javascript 相关文章推荐
javascript 日期时间函数(经典+完善+实用)
May 27 Javascript
COM中获取JavaScript数组大小的代码
Nov 22 Javascript
javascript中setTimeout的问题解决方法
May 08 Javascript
js同源策略详解
May 21 Javascript
javascript中$(function() {});写与不写有哪些区别
Aug 10 Javascript
JavaScript位置与大小(1)之正确理解和运用与尺寸大小相关的DOM属性
Dec 26 Javascript
ECMAScript6--解构
Mar 30 Javascript
如何将你的AngularJS1.x应用迁移至React的方法
Feb 01 Javascript
vue打包之后生成一个配置文件修改接口的方法
Dec 09 Javascript
vue实现验证用户名是否可用
Jan 20 Vue.js
js实现弹框效果
Mar 24 Javascript
vue项目中的支付功能实现(微信支付和支付宝支付)
Feb 18 Vue.js
学习使用ExpressJS 4.0中的新Router的用法
Nov 06 #Javascript
vue项目上传Github预览的实现示例
Nov 06 #Javascript
React Component存在的几种形式详解
Nov 06 #Javascript
支付宝小程序tabbar底部导航
Nov 06 #Javascript
利用JavaScript缓存远程窃取Wi-Fi密码的思路详解
Nov 05 #Javascript
利用hasOwnProperty给数组去重的面试题分享
Nov 05 #Javascript
微信小程序实现底部导航
Nov 05 #Javascript
You might like
PDO防注入原理分析以及注意事项
2015/02/25 PHP
初识通用数据库操作类――前端easyui-datagrid,form(php)
2015/07/31 PHP
PHPCMS忘记后台密码的解决办法
2016/10/30 PHP
thinkPHP5框架路由常用知识点汇总
2019/09/15 PHP
javascript实现的鼠标链接提示效果生成器代码
2007/06/28 Javascript
express的中间件basicAuth详解
2014/12/04 Javascript
JavaScript DOM进阶方法
2015/04/13 Javascript
JavaScript数据类型判定的总结笔记
2015/07/31 Javascript
js跨域资源共享 基础篇
2016/07/02 Javascript
JS版微信6.0分享接口用法分析
2016/10/13 Javascript
Vue.js第四天学习笔记(组件)
2016/12/02 Javascript
js实现倒计时效果(小于10补零)
2017/03/08 Javascript
jsonp跨域请求详解
2017/07/13 Javascript
微信小程序之前台循环数据绑定
2017/08/18 Javascript
vue 中filter的多种用法
2018/04/26 Javascript
解决Vue-Router升级导致的Uncaught (in promise)问题
2020/08/07 Javascript
Python发送email的3种方法
2015/04/28 Python
收藏整理的一些Python常用方法和技巧
2015/05/18 Python
Python导入oracle数据的方法
2015/07/10 Python
举例讲解Linux系统下Python调用系统Shell的方法
2015/11/07 Python
python http基本验证方法
2018/12/26 Python
解决Tensorflow sess.run导致的内存溢出问题
2020/02/05 Python
Python中格式化字符串的四种实现
2020/05/26 Python
Numpy 多维数据数组的实现
2020/06/18 Python
Pytorch mask-rcnn 实现细节分享
2020/06/24 Python
Java工程师面试集锦之Spring框架
2013/06/16 面试题
新闻记者实习自我鉴定
2013/09/19 职场文书
招商经理岗位职责
2013/11/16 职场文书
心理健康心得体会
2014/01/02 职场文书
小学端午节活动方案
2014/03/13 职场文书
临时工聘用合同协议书
2014/10/29 职场文书
2015法院个人工作总结范文
2015/05/25 职场文书
八月迷情观后感
2015/06/11 职场文书
2019年年中职场激励人心语录30条
2019/08/07 职场文书
vue2实现provide inject传递响应式
2021/05/21 Vue.js
教你使用Jenkins集成Harbor自动发布镜像
2022/04/03 Servers