热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

处理小程序内嵌h5缓存问题

该处理方案非原创,出处是收费的,地址就不贴出来了。下文是结合公司项目重新整理的,分享一下,独乐了不如众乐乐。缓存问题大家都知道,浏览器缓存是个非常有用的特性,它能够提升性能、减少推

该处理方案非原创,出处是收费的,地址就不贴出来了。

下文是结合公司项目重新整理的,分享一下,独乐了不如众乐乐。

缓存问题

大家都知道,浏览器缓存是个非常有用的特性,它能够提升性能、减少推迟,还可以减少带宽、降低网络负荷。关于浏览器的缓存机制可以总结成下面 2 句话:

  • 浏览器每次发起请求,都会先在浏览器缓存中查找该请求的结果以及缓存标识
  • 浏览器每次拿到返回的请求结果都会将该结果和缓存标识存入浏览器缓存中

更进一步,我们可以粗略理解一下强制缓存和协商缓存的运行机理。若强制缓存(Expires 和 Cache-Control)生效则直接使用缓存,若不生效则进行协商缓存(Last-Modified/If-Modified-Since 和 Etag/If-None-Match),协商缓存由服务器决定能否使用缓存,若协商缓存失效,那么代表该请求的缓存失效,返回 200,重新返回资源和缓存标识,再存入浏览器缓存中;生效则返回 304,继续使用缓存。这段文字是想让读者拓展一下知识面,假如想要更输入理解,可以通过上面的少量关键字(强缓存、协商缓存、Expire、Cache-Control 等)去查找更详细的资料。

微信的 web-view 组件就是一个嵌在小程序里的浏览器,它在缓存上并没有完全遵照上述的规则,也即它的缓存并不能及时得到清除。想必下面的操作大家都有尝试过:

  • 手动退出小程序,再次进入;
  • 将微信从后端退出再打开并重新进入小程序;
  • 修改 Nginx 关于 Cache-Control 的配置;
  • 用 debugx5.qq.com 手动清理安卓微信浏览器缓存;
  • iOS 利用微信自带清楚缓存功能。

无法及时刷新缓存会导致发布了最新的页面,而小程序里依然是以前的页面,从而会带来许多问题,如前后台的数据不一致,新的特性无法及时起作用,修改的问题没有得到处理等等。这里需要说明一下:web-view 在过一段时间(时间不定,一天或者者几小时,无显著规律)是可以进行缓存刷新的,而本 Chat 要处理的是及时刷新的问题。

处理问题

处理思路

浏览器访问资源是通过 URL 地址,假如内嵌 H5 的地址不发生变化,那么 web-view 访问资源会从缓存里取,而缓存里并没有最新的数据,这就导致了服务端的最新资源根本无法到达浏览器,这也就解释了为什么修改 Nginx 的 Cache-Control 配置也无法生效的起因。所以,要想彻底处理及时刷新,必需让 web-view 去访问新的地址。我们假定小程序访问的 URL 地址为:

https://www.yourdomain.com/101/#/index

其中 101 就是构建的一个版本号,每次递增,保证次次不同就可。

先来看一遍大概的流程图

处理小程序内嵌h5缓存问题流程图.png

小程序获取最新版本号

  • 在原生小程序中,我们利用 app 的 onShow 钩子函数 [1] 来完成最新的 URL 获取,同时还要保证只有获取了版本号之后才能加载其余的页面,因而这里要用到同步接口调用 [2]。请参考下面代码:

//这里加入同步请求到服务器获取最新路径

onShow: function (options) { this.getFEVersion()},getFEVersion: function () { //下面是利用Promise进行同步调用的写法 return new Promise(function (resolve, reject) { wx.request({ //下面是本机调试的一个地址,上线时请改成自己服务端的地址 url: ‘http://192.168.0.168:8090/getFEVersion’, data: {}, method: ‘POST’, header: { ‘content-type’: ‘application/json’, }, success: function (res) { if (res.data.success) { const app = getApp(); //res.data.version 是从服务端返回的最新fe的版本号,即上面的数字101 app.globalData.feUrl = ‘https://www.yourdomain.com/' + res.data.version + ‘/#/index’ } resolve(); }, fail: function (error) { console.log(error); reject(); } }) }); },

  • Taro中,同样的思路

// 接口const H5Rquest = { // 获取小程序内嵌h5对应的版本号(对应nginx匹配的文件夹路径) getH5Version() { return fetch.get(`/api/xxx/${version}/xxx/getH5Version`); },};// 调用接口componentDidMount() { H5Rquest.getH5Version() .then((res) => { console.log(res); if (!res || !res.data) { return WxActions.fnShowToast('无法获取版本号'); } let params = getCurrentUserParams(this.props.chooseChild); params = { ...params, gitlen: baseH5, id: this.$router.params.noticeId, isEdit: this.$router.params.isEdit, }; const src = `${h5HostName}/${res.data}/#/newsBulletin_announce?${qs.stringify(params)}`; console.log(src);// 调试模式可以看到跳转的路径能否跟需要的一致 this.setState({src}); }) .catch((err) => { console.log(err);// 报错信息已经统一阻拦输出 });}// html代码render() { const {src} = this.state; return ;}

Nginx 配置

Nginx 正则规则,~ 表示区分大小写的正则匹配,\d 是数字的匹配的正则表达式,正好可以匹配 101 这样的数字表达式。

server{ ##其余配置 ##…… ##其余配置 location ~ /\d { root /mnt/projects/FE/; }}

在服务器上存放项目的路径为 /mnt/projects/FE/101,下图是 Vue 项目构建好的样子。

000.png

服务端接口

下面是服务端接口的参考代码,我们可以将最新的版本号存入数据库:

@RequestMapping(value = “getFEVersion”, method = RequestMethod.POST)*public* Object *getFEVersion*(HttpServletRequest request) { ResponseVo respOnseVo= *new* ResponseVo(); //从数据库中取得最新的版本号 responseVo.setSuccess(“101”); *return* responseVo;}总结

到此,我们将小程序发布上线,重启 Nginx 使得配置生效,后续每次构建前台工程,都生成一个新的版本号,如 102、103 等等,将该版本号填入数据库中,后台接口都会及时返回最新版本号,使得小程序总是以最新的路径加载,从而做到 web-view 都能及时的加载最新的 H5 页面。
另外,在链接后面增加时间戳应该也是可以的,具体没验证过,不过哪怕可以,也会造成性能白费的问题,由于相当于每次进入都要重新下载代码,会导致客户体验不好。代码如下

const src = `${h5HostName}/index.html?stamp=${new Date().getTime()}#/WatchBaby?${qs.stringify( skipParams, )}`; console.log(src);

综上所述,通过接口生成版本号是比较保险的。

注解

[1]:在 app 的 onShow 钩子函数是小程序启动,或者从后端进入前端显示时触发,而且它是所有其余页面 onShow 钩子函数中第一个被执行,因而在这里进行最新版本获取。

[2]:因为需要取得最新版本才能进行其余业务,因而使用同步接口,以此来保证各个生命周期执行的顺序性。


推荐阅读
  • 使用nodejs爬取b站番剧数据,计算最佳追番推荐
    本文介绍了如何使用nodejs爬取b站番剧数据,并通过计算得出最佳追番推荐。通过调用相关接口获取番剧数据和评分数据,以及使用相应的算法进行计算。该方法可以帮助用户找到适合自己的番剧进行观看。 ... [详细]
  • 这是原文链接:sendingformdata许多情况下,我们使用表单发送数据到服务器。服务器处理数据并返回响应给用户。这看起来很简单,但是 ... [详细]
  • iOS超签签名服务器搭建及其优劣势
    本文介绍了搭建iOS超签签名服务器的原因和优势,包括不掉签、用户可以直接安装不需要信任、体验好等。同时也提到了超签的劣势,即一个证书只能安装100个,成本较高。文章还详细介绍了超签的实现原理,包括用户请求服务器安装mobileconfig文件、服务器调用苹果接口添加udid等步骤。最后,还提到了生成mobileconfig文件和导出AppleWorldwideDeveloperRelationsCertificationAuthority证书的方法。 ... [详细]
  • 本文讨论了如何使用Web.Config进行自定义配置节的配置转换。作者提到,他将msbuild设置为详细模式,但转换却忽略了带有替换转换的自定义部分的存在。 ... [详细]
  • Android实战——jsoup实现网络爬虫,糗事百科项目的起步
    本文介绍了Android实战中使用jsoup实现网络爬虫的方法,以糗事百科项目为例。对于初学者来说,数据源的缺乏是做项目的最大烦恼之一。本文讲述了如何使用网络爬虫获取数据,并以糗事百科作为练手项目。同时,提到了使用jsoup需要结合前端基础知识,以及如果学过JS的话可以更轻松地使用该框架。 ... [详细]
  • Hibernate延迟加载深入分析-集合属性的延迟加载策略
    本文深入分析了Hibernate延迟加载的机制,特别是集合属性的延迟加载策略。通过延迟加载,可以降低系统的内存开销,提高Hibernate的运行性能。对于集合属性,推荐使用延迟加载策略,即在系统需要使用集合属性时才从数据库装载关联的数据,避免一次加载所有集合属性导致性能下降。 ... [详细]
  • 在Docker中,将主机目录挂载到容器中作为volume使用时,常常会遇到文件权限问题。这是因为容器内外的UID不同所导致的。本文介绍了解决这个问题的方法,包括使用gosu和suexec工具以及在Dockerfile中配置volume的权限。通过这些方法,可以避免在使用Docker时出现无写权限的情况。 ... [详细]
  • 如何去除Win7快捷方式的箭头
    本文介绍了如何去除Win7快捷方式的箭头的方法,通过生成一个透明的ico图标并将其命名为Empty.ico,将图标复制到windows目录下,并导入注册表,即可去除箭头。这样做可以改善默认快捷方式的外观,提升桌面整洁度。 ... [详细]
  • 阿,里,云,物,联网,net,core,客户端,czgl,aliiotclient, ... [详细]
  • http:my.oschina.netleejun2005blog136820刚看到群里又有同学在说HTTP协议下的Get请求参数长度是有大小限制的,最大不能超过XX ... [详细]
  • 本文介绍了Web学习历程记录中关于Tomcat的基本概念和配置。首先解释了Web静态Web资源和动态Web资源的概念,以及C/S架构和B/S架构的区别。然后介绍了常见的Web服务器,包括Weblogic、WebSphere和Tomcat。接着详细讲解了Tomcat的虚拟主机、web应用和虚拟路径映射的概念和配置过程。最后简要介绍了http协议的作用。本文内容详实,适合初学者了解Tomcat的基础知识。 ... [详细]
  • Jquery 跨域问题
    为什么80%的码农都做不了架构师?JQuery1.2后getJSON方法支持跨域读取json数据,原理是利用一个叫做jsonp的概念。当然 ... [详细]
  • ps:写的第一个,不足之处,欢迎拍砖---只是想用自己的方法一步步去实现一些框架看似高大上的小功能(比如说模型中的toArraytoJsonsetAtt ... [详细]
  • angular.element使用方法及总结
    2019独角兽企业重金招聘Python工程师标准在线查询:http:each.sinaapp.comangularapielement.html使用方法 ... [详细]
  • Vue基础一、什么是Vue1.1概念Vue(读音vjuː,类似于view)是一套用于构建用户界面的渐进式JavaScript框架,与其它大型框架不 ... [详细]
author-avatar
agree_6398026768
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有