spa单页面应用html缓存问题

一、背景

浏览器的http请求都有一个缓存机制,简单点说就是同路径同名文件会默认被缓存下来,提升下次访问时的速度,默认只有刷新页面或长时间未访问时才会刷新缓存。

而spa单页面应用是通过路由切换来访问不同页面,路由切换时不会刷新页面,所有会存在缓存问题。

为了避免这个问题,一般都会配置文件名hash,hash一般采用content hash,文件内容有修改时就会生成新的文件名hash,防止项目修改发布后由于浏览器缓存导致页面未更新。

然而对于index.html模板文件,一般是不做hash处理的,在没有做特殊处理的情况下这个index.html文件会一直被浏览器缓存,由于所有的js/css等资源文件名的引入都是在html里,如果html模板文件未更新,就会导致项目修改发布了也未及时生效的问题,在pc端浏览器里可以通过手动刷新页面处理,而在移动端特别是hybrid混合应用里就束手无策了。

二、http缓存

每个浏览器都实现了 http 缓存,http的缓存机制在网上能找到一堆文章,这里就简单总结一下,不做详细说明。
http缓存分为强缓存和协商缓存,缓存配置只能通过服务端设置,前端无法控制

1、强缓存

  • 强缓存通过响应头中的 Cache-Control 或 Expires 字段来设置,Cache-Control 优先级更高。
  • 可设置为长期或指定时间或强制不缓存,
  • 优先级高于协商缓存,
  • 配置了强缓存的页面需要通过ctrl+f5来强制刷新页面。
  • Cache-Control 的 no-cache 和 no-store 的区别:no-cache是需要先经过服务端校验,读取协商缓存规则;no-store是完全禁用客户端缓存。

2、协商缓存

  • 协商缓存通过响应头中的 Etag 或 Last-Modified 字段来设置,Etag 优先级更高。
  • 配置了协商缓存后下次访问时请求头会自动带上 If-None-Match 或 If-Modified-Since 字段,服务端通过请求头里的这个值和服务端访问文件的值作对比来判断服务端文件是否已更新,已更新返回200重新获取,未更新返回304从缓存读取。
  • Etag是对比文件的hash值,Last-Modified 是对比文件的最后更新时间。
  • 优先级低于强缓存
  • 配置了协商缓存的页面通过f5或鼠标点击刷新按钮即可刷新页面。

三、解决html文件缓存

了解了http的缓存机制后就能找到解决方案了,也就是配置协商缓存或强缓存两种基本方案,以nginx服务器为例。

1、协商缓存方案

Etag 和 Last-Modified 选择一种即可,都设置也行,推荐Etag,也就是在服务端开启etag。

  • nginx配置示例:
http {
    etag: on;
}
  • 注意不要同时开启强缓存,否则会覆盖协商缓存配置。

2、强缓存方案

理论上来说配置协商缓存后html缓存问题就能解决,实际上浏览器环境比较复杂,不同环境表现并不一致。
特别是app或小程序的webview,页面缓存比较顽固,有时候协商缓存不起效果,可以考虑配置强缓存方案,即强制不缓存。

Cache-Control 或 Expires 选择一种即可,推荐Cache-Control。

  • nginx配置示例:
location / {
    if ($request_filename ~* .*\.html$) {
        add_header Cache-Control "no-cache, no-store";
    }
}

(这里Cache-Control只配置no-store也行)

  • 如果项目放在域名下子目录,以子目录名为h5为例:
location ^~ /h5 {
    if ($request_filename ~* .*\.html$) {
        add_header Cache-Control "no-cache, no-store";
    }
}
  • 如果同时放在子目录h5且使用history模式:
location ^~ /h5 {
    root  html;
    try_files $uri $uri/ /h5/index.html;
    if ($request_filename ~* .*\.html$) {
        add_header Cache-Control "no-cache, no-store";
    }
}

四、验证方式

这里介绍一下方法验证是否生效:

  • 首先浏览器f12打开开发者工具,切换到network栏,点击Doc筛选栏,
    在这里插入图片描述
  • 如图,Doc即document,可以筛选出主路由的html文件请求(上述home路由即index.html),只需查看该请求的status状态码和size即可判断。
  • 304状态码就表示触发了协商缓存,200状态码且size显示为disk cache或memery cache即表示为触发了强缓存,200状态码且size显示为实际大小表示正常请求数据未触发缓存。
  • 由于缓存是第二次访问才会触发,且刷新浏览器不走缓存,所以要加以验证可以这么做:先访问页面,然后改变浏览器的域名地址回车,让浏览器访问另一域名的网址,然后点击浏览器的后退按钮,这是再查看页面的status和size状态即可判断。
  • 如果通过强缓存方案设置html强制不缓存,查看结果如下:
    在这里插入图片描述
    在这里插入图片描述
  • 对于做app和小程序内嵌webview的h5开发来说,处理html缓存问题很有必要。

关键词:vue react 清除html缓存


参考链接:
https://blog.csdn.net/weixin_40817115/article/details/86707180

  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值