记一次将请求改为协商缓存的艰难过程

简单回顾一下前端缓存策略 ⛏️

  1. 强缓存:在请求头规定的max-age和expirse过期之前直接读取本地缓存的资源,如果已经过期则调用协商缓存
  2. 协商缓存:也叫弱缓存,以下都称为协商缓存。协商缓存是缓存过期,刷新缓存时间或者文件更新,返回新文件的缓存阶段。
    • 以下是协商缓存的过程:
    • 前端 首次 请求文件、静态资源时,请求响应头带上Etag/Last-Modified请求头
    • 告诉浏览器下一次同样的资源请求需要在请求头带上If-None-Match:值为上一个请求响应头的Etag,If-Modified-Since:值为上一个请求响应头的Last-Modified,服务器根据请求头的这两个字段匹配资源是否变更
    • 如果未变更,他们的值应该是一样的,返回304即可。如果变更了,值不一样,返回200和新的资源内容
    • 所以非首次请求资源才会带上If-None-Match/If-Modified-Since
    • 但是响应头每次都会带上Etag/Last-Modified(文件、静态资源会自动携带因为可能需要缓存,json字符串接口不会自动携带,普通接口不需要也不应该缓存)
  3. 新手请记住强缓存和协商缓存容易混淆的地方,强缓存和协商缓存不是非我即他的两种独立使用的策略。而是包含关系的缓存策略。强缓存开启一定包含协商缓存,因为强缓存资源到期需要使用协商缓存刷新强缓存的缓存时间
  4. 协商缓存的策略使用也是使用Cache-Control: max-ag=0(或者设置为no-cache)将强缓存时间设置为0强制开启协商缓存。强缓存和协商缓存可以理解为是前端缓存的不同阶段

需求背景 🔥

  1. 项目有一个全局请求配置文件的轮询接口,他会在发版时变更,轮询发现配置文件有变更则提示用户刷新页面,启用新版本。
  2. 但是有一天出BUG了,发版成功,但是客户端没有检测到版本变化。
  3. 打开Console控制台一看,原来接口被强缓存了,接口返回200(from disk cache),读取本地缓存文件肯定没有变化,检测不到发版更新。
    image.png

开始爬坑  ✏️

开始发现问题是开启了强缓存,心想这还不简单,直接改为弱缓存解决,easy。
还是太年轻了🤡🤡🤡
  1. 查阅MDN将Cache-Control设置为no-cache即可开启协商缓存
  2. 这里注意一下,no-cache不是不使用缓存,是每次都去服务器验证一下资源是否变更,变更则返回200和变更后的资源,未变更则返回304使用缓存。no-store才是不使用缓存。
    image.png

第一个坑:本地调试开启https没有合法证书缓存无效,本地改为http正常

  1. 查看请求,请求头加上了Cache-Control: no-cache,响应头也返回了Etag,但是没有返回304
    image.png

  2. 但接口没有被缓存,依然每次直接请求服务器(304才是协商缓存,它返回了200)
    image.png

  3. 第一个坑问题解决

     最后发现是本地当时开了https联调第三方https的接口,但是没有本地关联证书,裸奔https而浏览器不会缓存没有合法证书的https请求后面一次发到测试上发现缓存是有效的,线上是https有合法证书然后本地去掉https,缓存也有效了,🤮吐血,浪费了我好多时间
    

第二个坑:Cache-Control: no-cache缓存无效,需要改为Cache-Control: max-age=0

总所周知,程序解决了第一个坑,总会有第二个坑等着你
  1. 查看MDN、谷歌、百度看网友示例,设置为no-cache都可以开启协商缓存,但是我这里第二次请求没有带上弱缓存的请求头(If-None-Match/If-Modified-Since)

  2. 如下图所示(非首次请求截图),Cache-Control为no-cache,响应头带上了Etag/Last-Modified,但是请求头没有带上弱缓存的请求头,接口直接返回200而不是304没有使用协商缓存
    image.png

  3. 花了很多时间找不到答案,累了毁灭吧,又不是不能用,协商缓存可能也就快了一点点而已,折腾啥又不能涨工资,无所谓.jpg QAQ。
    5d99306c27bb1ee45a93e3359f5dc542.jpeg

  4. 在我快要放弃的时候,我看到了可以试一下将Cache-Control设置为max-age=0,果然了就可以了

     max-age表示在给定的时间内(单位秒)使用强缓存,直接读取本地缓存文件超过时间则请求服务器验证文件是否变更
    

    image.png

  5. 虽然对了,但为什么no-cache不行,我看MDN和别人的代码示例都说no-cache是可以,我认为实际上应该也是可以的,可能是中间网关做了什么处理?我也尝试过是否开启了Disable cache,但是我一直都是关的。百撕不得其姐,有没有懂哥赐教🫡(respect)!

问题来了,最开始的代码根本没有配置Cache-Control怎么默认开启了强缓存

  1. 又发现了一个奇怪现象,当我将Cache-Control请求头去掉,还原场景。获取该配置文件的接口刚开始还是304好好的,然后穿插了几个200强缓存(而且后面强缓存还变成连续的),然后又变成了304到底怎么回事?(该请求轮询时间是30s)
    image.png
  2. 最后在知乎找到了答案,明明没有配置任何缓存策略,浏览器还是给我强缓存了?
  3. 大概意思是没有配置任何缓存策略时会启用启发式缓存,则缓存时间cacheTime为响应头返回的(Date-lastModified)*0.1,所以就会一开始都是304因为cacheTime很小马上就过期了(不够30s),当cacheTime随着时间推移(资源未被更改)会越来越大,超过轮询的30s就变成了200强缓存。然后变成2个连续的200强缓存。当这个资源10天都未更改,那么这个请求一天都是强缓存,然后造成了项目发版了,但是没有发版提醒的BUG。
  4. 前端福尔摩斯(自封)🧐

结论 🏆

  1. 协商缓存无效可能是本地开启了https,改为http
  2. 设置Cache-Control: no-cache可能无效,使用Cache-Control: max-age=0
  3. 此次爬坑其实对业务来说无关痛痒,因为根本都没有遇到性能问题,这点性能提升对用户来说也是无感知的,但是此次爬坑让我对前端的强弱缓存有了更深的了解,之前我的理解前端的强弱缓存因为需要依赖后端返回的Etag、Last-Modified字段,所以应该需要后端或者负责Nginx配置的运维去负责管理的,原来前端也可以进行控制。也算是不枉费自己瞎折腾吧。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/409449.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

JVM - 1.类加载子系统

1.类加载子系统 1.作用 1.负责从文件系统或网络中加载字节码(.class)文件,即将物理磁盘上的字节码文件加载到内存中,生成供程序使用的类对象 2.字节码文件要求在文件开头有特定的文件标识(CA FE BA BE)3.类加载器(ClassLoader)只负责字节码文件的加载&am…

pdf文件渲染到canvas

1、jQuery 2、Fabric.js Fabric.js是一个对canvas进行封装的Javascript库,主要的功能包括在canvas上创建和填充图形,比如矩形、圆形、多边形;生成的图像自带缩放、旋转、拖拽等功能。 3、PDF.js PDF.js 是一个使用 HTML5 构建的便携式文档格式…

在Linux中如何安装JDK

一、卸载JDK (可以不删除,直接安装新的JDK,然后修改环境变量) 1.1卸载使用yum安装的jdk 1.1.1卸载系统预安装的JDK 使用命令:yum list installed |grep java 注意:该命令只能查看使用yum命令安装的jav…

【架构-24】XML和JSON

XML(可扩展标记语言)和JSON(JavaScript对象表示法)是两种常用的数据格式,用于在不同系统之间传输和交换数据。它们各有优点和缺点,适用于不同的场景。下面是对XML和JSON的简要介绍以及它们之间的对比。 XM…

有关于算法备案的五大误区

有关于算法备案的五大误区 在这个数据为王的时代,算法已然成为推动社会前进的隐形巨轮。从搜索框中的每一次点击,到购物车里的每一件商品推荐,再到朋友圈里刷屏的动态,算法的身影无处不在,悄无声息地编织着我们的数字生…

提升文旅热度带动商家增收,抖音生活服务“心动大连”活动启动

8月22日,抖音心动之城大连系列活动(下称“心动大连”)启动仪式召开,主题为“遇见大连,心动无限”。活动由大连市人民政府指导,大连市文化和旅游局、抖音生活服务共同主办,旨在发挥抖音平台内容和…

opencv-python图像增强十六:图像马赛克

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言一、算法流程:二、算法实现:2.1 生成背板图:2.2 图片添加马赛克效果 三,整体代码实现:四&#xff0c…

点亮星星的世界:当小孩得了自闭症该怎么办

在这个丰富多彩的世界里,每一个孩子都是独一无二的天使。然而,有一些孩子却仿佛被困在了自己的小小世界中,难以与外界正常交流和互动。他们是自闭症儿童,他们的世界充满了挑战和困惑,也让家长们陷入了深深的担忧和焦虑…

UE5学习笔记17-让人物的视线和鼠标移动时的方向一致,并且不让人物模型旋转,只改变视线方向

一、创建标准动画帧 1.我想让人物在装备武器后根据鼠标的移动方向改变人物的视线方向,并且人物模型不会改变朝向 2.我的动画中存在一个四个方向瞄准的动画,将左下,坐上,左转,右上,右下,右转&…

Android - 音频参数合入

音频参数宏观来看分为两部分,audio和music。不管是哪个平台都需要分别合入这两部分。 A10 music参数 相关工程师调试后会提供 audio_para 文件,将该文件替换至对应工程下的文件编译即可 例: device/sprd/sharkle/sl8541e_1h10_32b/rootdir/system/et…

程序员失业跑滴滴,意外自学AI绘画成主业,月入过万不是梦!

一、突如其来的裁员 那是一个阴沉的下午,我像往常一样,在公司忙碌着。突然,HR叫我去会议室,告诉我由于公司业务调整,我所在的部门被整体裁撤。作为一名程序员,我从未想过自己会面临失业的困境。拿着那份补偿…

大语言模型-PDF文档解析

PDF解析能够提升大语言模型系统的信息处理能力和应用范围,为用户提供更加便捷、高效、个性化的服务体验。本文介绍三种常用的pdf解析方式:Open Parse、pdfplumber、PyMuPD。 一、Open Parse Open Parse是一个能够直观地识别文档布局并有效地对其进行分…

mac安装java17(jdk17)

1. 下载jdk17 官网下载:https://www.oracle.com/java/technologies/downloads 2. 直接安装 安装完后目录会存放在下面目录下 /Library/Java/JavaVirtualMachines 111111deMBP JavaVirtualMachines % ls jdk-11.0.227 jdk-17.jdk 3. 如果你已经安装过java&#…

kafka的12个重要概念

kafka的12个重要概念 1、服务器broker1.1、Broker 的主要功能1.2、Kafka Broker 的架构1.3、配置和管理1.4、高可用性和负载均衡1.5、总结 2、主题topic2.1、主要特点 3、事件Event4、生产者producer4.1、主要功能4.2、Producer 的配置选项4.3、Producer 的工作流程4.4、总结 5…

网页,html,Web端实现RTSP/RTMP实时推流视频和播放

随着技术的不断发展,实时流传输已经成为许多应用的重要组成部分。RTSP(Real-Time Streaming Protocol)作为一种实时流媒体传输协议,广泛应用于视频监控、直播等领域。然而,在Web端实现RTSP实时推流视频播放却面临一些挑…

谈下日本IT业现状以及未来的发展

日本IT业现状 市场规模与增长率: 根据最新数据,日本IT行业的市场规模在不断扩大。例如,2022年日本IT行业的总市值达到了约4500亿美元,年复合增长率约为3.5%。这表明该行业在经济中占据重要地位,并持续保持增长态势。就…

我忘记给我的代码备份了。。。。。。

ok啊,历经1个月,这个项目总算是快写完啦!很烧脑,写这个脑细胞都不知道噶了多少,哎~ 虽然目前还有很大一部分可以改进,我觉得以我目前的能力能写成这样已经很不错了,还是学艺不精啊~ 实际上的话…

分享一个基于python新闻订阅与分享平台flask新闻发布系统(源码、调试、LW、开题、PPT)

💕💕作者:计算机源码社 💕💕个人简介:本人 八年开发经验,擅长Java、Python、PHP、.NET、Node.js、Android、微信小程序、爬虫、大数据、机器学习等,大家有这一块的问题可以一起交流&…

SpringBoot集成kafka开发-消息消费的分区策略(消费者如何判断从哪个分区中消费消息的?)

这里写目录标题 1、kafak消息者消费消息的4种分区策略2、kafka默认的消费分区策略1-RangeAssignor(均匀分配、默认分配策略)2.1、代码验证RangeAssignor的消息分区策略2.1.1、消费者2.1.2、生产者2.1.3、kafak配置类2.1.4、对象实体类2.1.5、项目配置文件…

卸载通过pip安装的所有Python包的详细指南

卸载所有通过pip安装的Python包的方法总结(Windows系统) 方法 1: 使用 pip freeze 和 requirements.txt 步骤: 导出依赖到requirements.txt文件: pip freeze > requirements.txt这个命令会将当前环境中所有已安装的Python包及其版本号输出到requirem…