清除浏览器缓存之后为什么还是显示旧的html页面_Web缓存控制策略详解

管理Web缓存的最常用和最有效的方法之一是通过Cache-Control HTTP标头,由于此标头适用于Web页面的缓存,这意味着我们页面上的所有内容都可以具有非常精细化的缓存策略。通过各种自定义策略,我们控制的策略就可以变得非常复杂和强大。

7b1642dc17421b8164c60afadb5a55d2.png

Cache-Control

管理Web缓存的最常用和最有效的方法之一是通过Cache-Control HTTP标头,由于此标头适用于Web页面的缓存,这意味着我们页面上的所有内容都可以具有非常精细化的缓存策略。通过各种自定义策略,我们控制的策略就可以变得非常复杂和强大。

Cache-Control标头可能如下所示:

Cache-Control: public, max-age=31536000 

Cache-Control是标头,public和max-age=31536000都是指令。 Cache-Control标头可以接受一个或多个指令,我想在本文中讨论的就是这些指令,比如它们的真正含义以及它们的最佳用例。

public和private缓存

public意味着任何缓存都可以存储响应的副本,其中就包括CDN、代理服务器等。public指令通常是多余的,因为其他指令(比如max-age)的存在是隐式指令,缓存可能会存储一个副本。

另一方面,private是一个显式指令,只有响应的最终接收者(客户端或浏览器)才可以存储该文件的副本。虽然private本身不是具有安全功能,但是它的目的是防止public缓存(例如CDN)存储包含一个用户唯一信息的响应。

max-age

max-age定义了一个以秒为单位的时间单位(相对于请求的时间),该单位的响应被认为是‘fresh’。

Cache-Control: max-age=60 

此Cache-Control标头会告诉浏览器,它可以在接下来的60秒内使用缓存中的此文件,而不必担心重新被验证。 不过60秒后,浏览器将返回服务器以重新验证文件。

如果服务器有一个新文件供浏览器下载,它将以200响应进行响应,下载新文件后,旧文件将从HTTP缓存中弹出,新文件将替换它,并将成为新的缓存标头。

如果服务器没有需要下载的更新副本,则服务器将以200响应进行响应,不需要下载任何新文件,并将使用新的标头更新缓存副本。这意味着,如果仍然存在Cache-Control:max-age = 60标头,则缓存文件在60秒后将再次启动。算下来,一个文件的总缓存时间为120秒。

注意:max-age会有自动警告的属性,如果浏览器过于陈旧,则max-age会提醒用户,但用户可以选择忽略此警告。浏览器可能会使用自己的试探法来决定是否在不重新验证文件的情况下发布文件的陈旧副本。这种行为有些不确定,所以很难确切地知道浏览器将实际做什么。为此,我们有一系列显式指令,可以用它们来扩充max-age。

s-maxage

s-maxage将优先于max-age指令,但仅限在共享缓存的上下文中使用。将max-age和s-maxage结合使用,你可以分别为private和public缓存(例如代理、CDN)提供不同的启动时间。

no-store

Cache-Control: no-store 

如果我们不想缓存文件怎么办?如果文件包含敏感信息怎么办?也许这是一个包含银行详细信息的HTML页面?或许这些信息对时间至关重要?也许是一个包含实时股票价格的页面?其实我们并不想在缓存中存储或提供任何类似的响应:我们总是希望丢弃敏感信息并获取最新的实时信息。这时,我们就要用到no-store指令。

no-store是一个非常强大的指令,不会将任何信息保存到任何缓存中,无论是private或其他缓存。

no–cache

Cache-Control: no-cache 

这是让大多数人误解的指令,no – cache存并不意味着“没有缓存”。这只是意味着“在你使用服务器重新验证缓存之前,不需要从缓存中提供副本就可以使用以前的缓存副本”。

no-cache实际上是一种非常聪明的缓存更新策略,这样就可以始终保证最新的缓存副本。除非服务器响应更快,否则no-cache将始终must-revalidate服务器才能释放浏览器的缓存副本,但如果服务器响应速度一般,网络传输只有一个文件的标头,则可以直接从缓存中抓取正文而不是重载。

因此,这是一种结合更新策略,并快速从缓存中获取文件的智能方法,但前提是它至少要获得一个HTTP标头响应。

无缓存的一个很好的用例几乎就是动态HTML页面,想想新闻网站的主页:它不是实时的,也不包含任何敏感信息,但理想情况下我们希望页面始终显示最新鲜的内容。我们可以使用cache-control:no-cache来指示浏览器首先检查服务器,如果服务器没有更新的东西(304),就会重用缓存的版本。如果服务器确实有一些更新鲜的内容,它会响应(200)并发送更新的文件。

提示:没有必要发送max-age指令和no-cache指令,因为重新验证的时间限制为零秒。

must-revalidate

更令人困惑的是,尽管上面的代码听起来应该称为must-revalidate,但事实证明,must-revalidate仍然具有自己的特点。

Cache-Control: must-revalidate, max-age=600 

must-revalidate需要一个相关的max-age指令,如上所示,我们把它设置为十分钟。此时,no-cache将立即与服务器重新验证,只有在服务器允许时才使用缓存副本时,must-revalidate才类似于一个宽限期no-cache。具体过程是这样的,在前十分钟,浏览器不会与服务器重新验证,但十分钟过后,它又返回服务器。如果服务器没有任何新内容,它将以304响应并且新的Cache-Control标头应用于缓存文件。然后再以十分钟为单位,如果在十分钟之后,服务器上有一个较新的文件,我们会收到200响应及其正文,并且本地缓存会更新。

proxy-revalidate

与s-maxage类似,proxy-revalidate是must-revalidate的public缓存的自定义版本,它只是被private缓存忽略了。

immutable

immutable是一个非常新的且非常简洁的指令,它告诉浏览器关于我们发送的文件类型的更多信息,该指令可以解决以下问题:用户刷新会导致浏览器重新验证文件,无论其新鲜度如何,用户刷新通常意味着以下任意情况必定发生:页面看起来不完整或者内容还和原来一样。

所以,我们有必要检查服务器上是否有更新的内容。

如果服务器上有更新的文件,我们肯定希望下载它。因此,我们将得到200响应,即一个新文件出现。但是,如果服务器上没有新文件,我们将得到304响应,即没有新文件,如果是专业,则整个延迟反应就没有意义了。如果我们重新验证许多导致延迟反应304的文件,可能会增加数百毫秒不必要的等待。

immutable是一种告诉浏览器文件有无可变内容的指令,如果内容无更新,则永远不会重新验证缓存。这样,就可以完全消除延迟时间。不过,immutable所指的可变或不可变文件的具体含义是什么?

style.css:当我们更改此文件的内容时,即使根本不更改其名称,这个文件也被认为是可变的。

style.ae3f66.css:这个文件是唯一的,它以基于其具体内容来命名的,所以一旦内容发生变化,我们就会得到一个全新的文件,此时,这个文件就被认为是不可变的。

我们将在Cache Busting部分中更详细地讨论这个问题。

如果我们能够以某种方式向浏览器发出文件是不可变的信号,则它就不需要检查更新版本,这正是immutable指令的作用:

Cache-Control: max-age=31536000, immutable

在支持immutable指令的浏览器中,用户刷新永远不会在31536000秒的新鲜度生命周期内进行重新验证。这意味着无需花费不必要的延迟时间来检索304响应,这可能会在关键路径(CSS blocks rendering)上节省大量的延迟时间。

注意:你不应该将immutable应用于任何不可变的文件,因为你还应该有一个非常强大的缓存破坏策略。

stale-while-revalidate

到目前为止,我们已经谈了很多关于重新验证的内容,都是关于浏览器返回服务器以检查是否有更新的文件的过程。在高延迟连接上,重新验证的持续时间会很长,并且这个时间是固定的,直到我们对服务器进行额外的命令,否则既不能释放缓存副本(304)也不能下载新文件(200)。

stale-while-revalidate提供的是宽限期,在此期间,当我们检查新版本时,允许浏览器使用过去的缓存。

Cache-Control: max-age=31536000, stale-while-revalidate=86400 

该指令是在告诉浏览器“这个文件可以使用一年,一年之后,还可以再用一个星期。在这时候,如果你要继续使用这个旧的资源,就必须在后台重新验证它”。

stale-while-revalidate对非关键资源是一个很好的指令,当然,我们希望使用最新的版本。但是我们知道,如果在检查更新时再次使用过时的响应,不会造成任何对更新的破坏。

stale-if-error

与stale-while-revalidate类似,如果重新验证的资源返回5xx类错误,stale-if-error允许浏览器有一段缓冲时间,在此期间可以允许返回过时的响应。

Cache-Control: max-age=2419200, stale-if-error=86400 

在本文中,我们指定了28天(2419200秒)以内的缓存文件都是新的,如果我们在那之后遇到更新错误,我们会多追加一天(86400秒),在此期间我们将允许过时的资源响应。

Cache Busting(缓存破坏)

只讨论缓存得正常情况而不讨论缓存破坏的情况是不负责任的。在考虑你的缓存策略之前,我总是建议你解决缓存破坏策略。因为当开发者修改了网站就会发生问题,因为用户本地缓存的文件还是老文件。这样用户看到的不仅还是旧的功能,如果网站缓存了css和js文件,它们还在引用不存在的元素或者被移除的被重命名的元素,网站就会报错破坏。

Cache busting就是强制浏览器下载新文件的一种方法,通过将新文件的名字修改成和旧文件不同的名字即可实现。

No Cache Busting – style.css

这是最不可取的做法:绝对没有任何缓存破坏。这是一个可变文件,我们真的很难实现Cache Busting。

你应该非常谨慎地缓存这些文件,因为一旦它们出现在用户的设备上,我们几乎失去了对它们的所有控制权。

尽管这个例子是一个样式表,但HTML页面正好就是这个特性。由于我们无法更改网页的文件名,网站就会报错破坏!这正是我们根本不会缓存它们的原因。

Query String – style.css?v=1.2.14

此时,我们仍然有一个可变文件,但我们在其文件路径中添加了一个查询字符串。虽然这比什么都不做要好,但它仍然不完美。如果要删除查询字符串,我们会回到之前的类别,即完全不存在缓存破坏。许多代理服务器和CDN都不会通过配置来缓存任何带有查询字符串的内容。例如,来自Cloudflare的文档, “style.css?something”的请求将被标准化为“style.css”,或查询字符串可能包含特定于一个特定响应的信息。

Fingerprint – style.ae3f66.css

到目前为止,指纹识别是缓存破坏文件的首选方法。每次文件的内容发生变化时,我们都对其进行更改,这并不会缓存任何内容。这意味着,我们将最终得到的是一个全新的文件!且该文件不可更改。如果你可以在静态缓存上实现此功能,请执行此操作!一旦你成功地实现了这个非常可靠的缓存破坏策略,你就能得到最强的缓存控制指令了:

Cache-Control: max-age=31536000, immutable 

实施细节

此方法的关键是更改文件名,但不一定是对指纹进行更改。以下所有示例都具有相同的效果:

  • /assets/style.ae3f66.css:使用文件内容的哈希产生破坏;
  • /assets/style.1.2.14.css:使用一个已发布的版本产生破坏;
  • /assets/1.2.14/style.css:通过更改URL中的目录产生破坏;

但是,最后一个示例表明,我们对每个版本而不是每个单独的文件进行版本控制。这反过来意味着,如果我们只需要缓存样式表,则还必须缓存该版本的所有静态文件,所以首选选项是前两个。

Clear-Site-Data

目前我们正在开发一个规范,以帮助开发人员确定整个缓存的来源,并从根上彻底一次性清除,这就是Clear-Site-Data的含义,它让Web开发人员对浏览器本地存储的数据有更多控制能力。

我不想在这篇文章中详细介绍Clear-Site-Data,它不是Cache-Control指令,而是一个全新的HTTP标头文件。

Clear-Site-Data: "cache" 

将此标头应用于你的任何一个源缓存都将让整个源的缓存破坏,而不仅仅是它所附加的文件。这意味着,如果你需要从所有访问者的缓存中强制破坏整个站点,则可以将上述标头应用于HTML有效内容。

在撰写本文时,仅支持浏览器有Chrome,Android Webview,Firefox和Opera。

提示:Clear-Site-Data将接受许多指令:“cookies”,“storage”,“executionContexts”和“*” (当然,“*”的意思是“以上所有”)。

具体示例

好的,让我们来看看一些应用场景以及我们可能采用哪种Cache-Control标头。

网上银行页面

Request URL: /account/ Cache-Control: no-store 

根据规范,这足以阻止浏览器在private和共享缓存中持续对磁盘的响应。

no-store响应指令会命令缓存不得存储立即请求或响应的任何部分,此指令适用于private和共享缓存。 “不得存储”意味着缓存不得故意将信息存储在非易失性存储中,并且必须尽最大努力尽快在转发后从易失性存储中删除所存储的信息。

但如果你想要防止缓存的发生,你可以选择:

Request URL: /account/ Cache-Control: private, no-cache, no-store 

该指令将明确指示不要在public缓存(例如CDN)中存储任何内容,以始终提供最新的副本。

列车时间表网页

如果我们正在构建一个显示实时信息的页面,则希望保证用户始终能够看到最新的信息。此时,可以使用以下指令:

Request URL: /live-updates/ Cache-Control: no-cache 

这个简单的指令意味着浏览器不会直接从缓存中显示响应,意味着页面不会显示过时的列车信息。

FAQ页面

像FAQ这样的页面可能很少更新,因为其中的内容大多都是常识性问题,对时效性没有要求。我们可能会暂时缓存这样的HTML页面,并强制浏览器定期检查新内容,而不是每次对缓存进行访问。可以使用以下指令:

Request URL: /faqs/ Cache-Control: max-age=604800, must-revalidate 

该指令会告诉浏览器将HTML页面缓存一周(604800秒),并且一周结束后,我们需要检查服务器是否有更新。

页面中的图片

页面中的图片通常都是一篇文章的配图,通常我们都会下载下来,所以我们想缓存它。但其实它对页面的更新状态并不会产生影响,因此我们不需要它的更新状态。可以使用以下指令:

Request URL: /content/masthead.jpg Cache-Control: max-age=2419200, must-revalidate, stale-while-revalidate=86400 

该指令会告诉浏览器将图像存储28天(2419200秒),我们要在28天的时间限制后检查该图像在服务器中是否有更新。

总结

1.判断是否设置了cacheBusting属性非常重要。在开始执行缓存策略之前,请先制定缓存破坏策略。

2.一般来说,缓存HTML内容是一个错误的方法。 由于HTML网址不能被破坏,并且由于你的HTML页面通常是其余子资源的入口点,因此你最终也会缓存对静态资源的引用。

3.如果要缓存任何HTML,在站点上的不同类型的HTML页面上使用不同的缓存策略可能会导致不一致,比如有的页面总是最新的内容,而其他页面的内容有时是从缓存中获取的。

4.如果你能够可靠的缓存(使用指纹)的静态资产,那么你还不如一次性使用一个不可变的指令缓存数年,以便更好地进行管理。

5.非关键缓存内容可以使用stale-while-revalidate等指令,增加缓存的宽限期。

6.immutable和stale-while-revalidate不仅为我们提供了缓存的传统优势,而且还允许我们在重新验证时降低延迟。

7.充分了解你的缓存,并设计具有针对性的缓存策略。

天下数据IDC与全球近120多个国家顶级机房直接合作,包括香港、美国、韩国、日本、台湾、新加坡、荷兰、法国、英国、德国、埃及、南非、巴西、印度、越南等国家和地区的服务器、云服务器的租用服务!

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

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

相关文章

java jtextfield 事件_JAVA JTextField事件处理

初学JAVA,笔记:package windows;import javax.swing.*;import java.awt.*;import java.awt.event.*;class WindowFlow extends JFrame implements ActionListener{private static final long serialVersionUID 1L;JTextField text1,text2;WindowFlow(St…

js封装函数_JavaScript基础-如何封装函数来改变元素的位置

点击右上方红色按钮关注“小郑搞码事”,每天都能学到知识,搞懂一个问题!大家好!我是/小郑搞码事/的小郑今天给大家分享JavaScript的基础知识-改变元素的位置。没错,用JS实现过动画的同学都应该了解一点,简单…

java程序设计与实践教程 王薇 doc_Java程序设计与实践教程 王薇主编 答案

Java程序设计与实践教程 王薇 主编 董迎红 副主编 课后习题 答案第1章 JAVA简介一、判断题1.√ 2.√ 3. 4. 5. 6.√ 7.√ 8.√ 9. 10.二、填空题1.Application Applet 2. 类(字节码文件、目标文件) .class3.对象 4. 主 5. J2SE J2EE J2ME三、选择题1.B 2. D 3.B 4.B 5. A四、简…

maya藤蔓插件_Maya特效制作之植物生长动画制作教程(二)之多条藤蔓动画制作...

四、制作多条蔓藤植物下面我们要让很多植物在这个“崖壁”上生长出来,也就是要重复很多次前面的工作,当然可以这样一步一步地做,在“崖壁”面片上手动画很多的线,但下面尝试一种新的方法来制作,让粒子在“崖壁”面片Pl…

mysql数据库导入导出_MySQL数据库导入导出详解

MySQL数据库的导入,有两种方法:1) 先导出数据库SQL脚本,再导入;2) 直接拷贝数据库目录和文件。在不同操作系统或MySQL版本情况1. 概述MySQL数据库的导入,有两种方法:1) 先导出数据库SQL脚本,再导…

代码统计工具有哪几种_跟我学“Linux”小程序Web版开发(四):引入统计及Crash收集...

在完成了产品的基础开发以后,接下来需要进行一些周边的工作,这些周边工具将会帮助下一步优化产品。在完成了产品的基础开发以后,接下来需要进行一些周边的工作,这些周边工具将会帮助下一步优化产品。为什么要加应用统计和 Crash 收…

错误:不能继续进行下一步操作 openfire 设置._如何为MacBook或Mac电脑恢复出厂设置...

mac电脑经过长时间的使用后会变得卡顿,或者因为部分操作方式改变以至于给我们在使用过程中造成障碍,此时我们可以进行恢复出厂设置,以此来解决部分问题。那么该如何为MacBook或Mac电脑恢复出厂设置呢?下面跟随小编来一起学习一下吧…

mac显示网速_Mac网络流量监控工具——NetWorker pro

NetWorker pro for Mac是Mac系统上一款轻量级的网速实时监测软件,可以让用户在菜单栏上显示当前的网络上传下载速度,可以在速度和流量两种模式之间切换,也可以选择不同的网络模式来进行监测。此外,networker mac还提供有关当前活动…

matlab gui学习手记_MATLAB论坛不可错过的30例GUI源代码

​过去的两年中,我经常会在微信公众号和知乎上分享,平时如何通过MATLAB制作GUI,来让自己的工作和生活更加便捷与高效。在分享的同时,有不少朋友会给我留言提问关于MATLAB GUI的问题。而其中的许多问题,其实都是能够在M…

线性回归csv数据集_用mxnet的gluon线性回归训练只有两个特征的数据集

前言自从上次试着用最基础的线性回归训练一个有80个特征的数据集,梯度爆炸之后,今天拿一个简单到不能再简单的数据集试试能不能成功收敛。途中我们又会遇到什么问题?数据集来自吴恩达机器学习课程第二周的课后练习。原本是txt文件&#xff0c…

java中include标签的用法_原 ng-include用法分析以及多标签页面的简单实现方式

在平时的项目开发中,应该会经常遇到上图所示的需求,就是在一个页面中有多个标签,被选中的标签颜色会高亮显示,切换不同标签显示相应的不同内容。如果内容代码过多则写在同一个html文件就会显得特别乱,所以这里我们最好…

禅道项目管理_禅道 11.6.1 版本发布,完善细节,修复 Bug

禅道项目管理软件集产品管理、项目管理、质量管理、文档管理、组织管理和事务管理于一体,是一款功能完备的项目管理软件,完美地覆盖了项目管理的核心流程。禅道官网:www.zentao.net。大家好,禅道项目管理软件11.6.1发布&#xff0…

mendeley引用参考文献不显示_免费文献管理器Mendeley

June 2020有机合成化学文献检索今天小编给大家分享一款免费又好用的文献管理器——Mendeley,另外晶体cif文件下载—Materialsproject和COD数据库可在菜单栏的文献检索[文献管理/资源]中查看Mendeley是什么Mendeley是一款免费的跨平台文献管理软件,同时也…

停车场管理系统代码_jsp19109商场商铺停车场服务系统-SSM-Mysql

jsp19109商场商铺停车场服务系统-SSM-Mysql该设计有演示视频    100%能运行买重包换  保密发送  一校一份编号:jsp19109语言数据库:jspMysql论文字数:12032字摘 要随着社会的发展,社会的方方面面都在利用信息化时代的优势。计…

qregexp限制数字范围_数字系统实现电压电流控制的必经之路数模转换器

《芯势力》系列接上一篇文章,我们了解到了模数转换器,本文将带你了解数模转换器。看名字就能知道,如果模数转换器实现了模拟信号到数字信号的转换,那么,数模转换器就是模数转换器的逆过程,即把数字信号转换…

js方式调用php_js如何调用php函数

js调用php函数的方法:jQuery.ajax({type: "POST",url: your_functions_address.php,dataType: json,data: {functionname: add, arguments: [1, 2]},success: function (obj, textstatus) {if( !(error in obj) ) {yourVariable obj.result;}else {conso…

最大子序列求和_算法——求最大子段和

一、问题描述给定由n个整数组成的序列(a_1,a_2,…,a_n),最大子段和问题要求该序列形如 的最大值(1≤i≤j≤n),当序列中所有整数均为负整数时,其最大子段和为0。例如,序列(-20, 11, -4, 13, -5, -2)的最大子段和为: 注意…

seo黑帽劫持用的php,黑帽seo 论坛:黑帽seo防止网站被k的js劫持跳转代码

由于目前百度搜索百度搜索引擎对于js代码还没有办法完全辨别,因此也就出现了运用js代码跳转的黑帽优化提升手法。现如今在网络上有关js跳转代码不计其数,但是作为黑帽优化提升的seo手法之一,如何确保有效降低跳转的网址被k危害性,…

oracle 同义词_【干货7】Oracle知识关键代码摘要

(如果我分享的干货内容对你有帮助,可以通过赞或者评论的方式告诉我,我会持续分享;或者留言你想要的IT方面的支持,我将分享大家感兴趣的IT类技术干货;如果没有收到大家的反馈,10天后我将停止技术…

qt做的接收串口数据并显示曲线_QT无人机地面站设计与制作

近年来,无人机可谓是大火。无论是军事,还是民用,它的地位更是不用说。但,如何利用利用现有技术对无人机的信息进行操作,实现人、机合一呢?“无人机地面站”应运而生,结合仿真系统为地面工作人员…