Web 缓存大致可以分为:数据库缓存、服务器端缓存(代理服务器缓存、CDN 缓存)、浏览器缓存。其中前端比较关心的是浏览器缓存,包括今天要说的HTTP缓存和前面说过的cookie、localStorage等存储。(资源缓存仅针对get请求,post、put、delete等行为性操作无缓存)。

HTTP缓存分为强缓存和协商缓存。通过特殊的HTTP中的cache-control首部和expries首部,说明文档是否过期,浏览器二次请求相同资源时,进行比较,没有过期则为强缓存。过期则核对是否修改,但是缓存过期仅代表需要进行核对,而不一定是资源有了差异,客户端和服务器端通过某种验证机制验证当前请求资源是否可以使用缓存,这便是协商缓存。

from-cache:

  • 200:缓存命中
  • 304:再匹配未修改(not modified)

强缓存

Cache-Control和Expires

强缓存利用Expires和Cache-Control两个字段来控制。expires:是缓存过期时间(即资源过期时间),是个绝对值。所以如果客户端更改时间,会导致缓存混乱。所以http1.1增加了cache-control,由多个字段组合而成,其中max-age 字段,它是一个相对的时间。

  • Cache-Control是HTTP1.1中新增的响应头,Expires是HTTP1.0中的响应头
  • Expires指定的是具体的过期日期而不是秒数,Cache-Control使用的是相对时间
  • Cache-Control和Expires同时使用的话,Cache-Control会覆盖Expires

Cache-Contro相关属性

max-age(单位为s)

指定设置缓存最大的有效时间,当浏览器向服务器发送请求后,在max-age这段时间里浏览器就不会再向服务器发送请求了。

public

指定响应可以在代理缓存中被缓存,于是可以被多用户共享。如果没有明确指定private,则默认为public。

private

响应只能在私有缓存中被缓存,不能放在代理缓存上。对一些用户信息敏感的资源,通常需要设置为private。

no-cache

表示必须先与服务器确认资源是否被更改过(依靠If-None-Match和Etag),然后再决定是否使用本地缓存。

no-store

绝对禁止缓存任何资源,也就是说每次用户请求资源时,都会向服务器发送一个请求,每次都会下载完整的资源。通常用于机密性资源。

协商缓存

浏览器或代理缓存中缓存的资源过期了,并不意味着它和原始服务器上的资源有实际的差异,仅仅意味着到了要进行核对的时间了。这种情况被称为服务器再验证,也就是协商缓存:

  • 如果资源发生变化,则需要取得新的资源,并在缓存中替换旧资源。
  • 如果资源没有发生变化,缓存只需要获取新的响应头,和一个新的过期时间,对缓存中的资源过期时间进行更新即可。

HTTP1.1推荐使用的验证方式是If-None-Match/Etag,在HTTP1.0中则使用If-Modified-Since/Last-Modified。

If-None-Match/Etag

Etag是指根据实体内容生成一段hash字符串,标识资源的状态,由服务端产生,第一次请求响应头会带上ETag: abcd,之后的请求中带上 If-None-Match: abcd。浏览器会将这串字符串传回服务器,验证资源是否已经修改,返回 304 或 200。

If-Modified-Since与Last-Modified

Last-modified: 服务器端资源的最后修改时间,响应头部会带上这个标识。第一次请求之后,浏览器记录这个时间,再次请求时,请求头部带上 If-Modified-Since 即为之前记录下的时间。服务器端收到带 If-Modified-Since 的请求后会去和资源的最后修改时间对比。若修改过就返回最新资源,状态码 200,若没有修改过则返回 304。这两个是HTTP1.0中用来验证资源是否过期的请求/响应头,这两个头部都是日期,验证过程与Etag类似,这里不详细介绍。使用这两个头部来验证资源是否更新时,存在以下问题:

  • 有些文档资源周期性的被重写,但实际内容没有改变。此时文件元数据中会显示文件最近的修改日期与If-Modified-Since不相同,导致不必要的响应。
  • 有些文档资源被修改了,但修改内容并不重要,不需要所有的缓存都更新(比如代码注释)

如果响应头中有 Last-modified 而没有 Expire 或 Cache-Control 时,浏览器会有自己的算法来推算出一个时间缓存该文件多久,不同浏览器得出的时间不一样,所以 Last-modified 要记得配合 Expires/Cache-Control 使用。

last-modified 和 Etag 区别

  • 某些服务器不能精确得到资源的最后修改时间,这样就无法通过最后修改时间判断资源是否更新。
  • Last-modified 只能精确到秒。
  • 一些资源的最后修改时间改变了,但是内容没改变,使用 Last-modified 看不出内容没有改变。
  • Etag 的精度比 Last-modified 高,属于强验证,要求资源字节级别的一致,优先级高。如果服务器端有提供 ETag 的话,必须先对 ETag 进行 Conditional Request。

应用

使用缓存的原因:

  • 冗余的数据传输
  • 带宽瓶颈
  • 瞬间拥塞
  • 距离时延

缓存场景:

  • CSS文件、js文件、html文件
  • 图标、图片
  • 供下载的附件

缓存时间:

  • 不经常改变的文件,设置较大的max-age,一般设置max-age=31536000(标准中规定 max-age 的值最大不超过一年,所以设成 max-age=31536000)
  • 经常需要变动的文件,Cache-Control: no-cache / max-age=0

前端HTTP缓存的更多相关文章

  1. 前端清除缓存方法(微信缓存引起的bug)

    bug1:在新版微信中,部门安卓机子(华为)出现window.location.href/window.location.reload....等方法来刷新本页面链接,发现页面没有被刷新,经过排查,发现 ...

  2. 深入浅出的webpack4构建工具---浏览器前端资源缓存(十一)

    阅读目录 一. 理解使用hash 二:理解使用chunkhash 三:对第三方库打包后使用缓存 四:contenthash 回到顶部 一. 理解使用hash 一般情况下,对于前端静态资源,浏览器访问的 ...

  3. Web前端的缓存机制(那些以代价换来的效率)

    对于Web前端而言,cache可以说是无处不在,通常是2个环节之间,就会引入一个cache做为提升整体效率的角色.例如A和B两者之间的数据交换,为了提升整体的效率,引入角色C,而C被用于当做热点数据的 ...

  4. HTML5之应用缓存---manifest---缓存使用----Web前端manifest缓存

    相信来查这一类问题的都是遇到问题或者是初学者吧! 没关系相信你认真看过之后就会知道明白的 这是HTML5新加的特性 HTML5 引入了应用程序缓存,这意味着 web 应用可进行缓存,并可在没有因特网连 ...

  5. 前端内容缓存技术:CSI,SSI,ESI

    一.CSI (Client Side Includes)   含义:通过iframe.javascript.ajax  等方式将另外一个页面的内容动态包含进来. 原理:整个页面依然可以静态化为html ...

  6. 缓存:前端页面缓存、服务器缓存(依赖SQL)MVC3

    缓存依赖数据库 第一步 1通过vs里面带的命令提示窗口. 2或者.NET Framework 版本 4(64 位系统)条件,%windir%\Microsoft.NET\Framework64\v4. ...

  7. 前端图片缓存之通过img标签加载GIF只能播放一次问题(转载)

    最近项目中要求再网页中插入一张gif图片,让用户每次到达该位置时动一次,所以我们就制作了一张只动一次的gif图片通过img标签引入.当用户进入该位置时,通过remove()清除图片然后重新append ...

  8. 前端不缓存,ajax不缓存,js操作cookie

    今天实现网站注销功能时,需要清除cookie缓存,开始在网上搜索的是“js清除缓存”,发现很多都是预先防患缓存存储的内容,千篇一律,不过也学习到了:后来换成"js清除cookie" ...

  9. 【移动前端开发实践】从无到有(统计、请求、MVC、模块化)H5开发须知

    前言 不知不觉来百度已有半年之久,这半年是996的半年,是孤军奋战的半年,是跌跌撞撞的半年,一个字:真的是累死人啦! 我所进入的团队相当于公司内部创业团队,人员基本全部是新招的,最初开发时连数据库都没 ...

随机推荐

  1. Python中文件读写之 w+ 与 r+ 到底有啥区别?

    其实r 是只读,只能读不能写,这是很明确的,但是r+是可读写,变成r+后还没太明白到底加了什么,还是照样写不了,有没有这样的体验呢,如下代码,只读时 f = open("test.txt&q ...

  2. 红帽学习笔记[RHCSA] 第六课[进程、服务相关]

    第六课 进程 进程:已经启动的可执行程序的运行中的实例.每个进程都有自己的地址空间,并占用了一定的系统资源. 如何产生一个进程 执行程序或命令 计划任务 在终端中对进程管理 运行一个前台进程 [roo ...

  3. 正反向代理、负载均衡、Nginx配置实现

    一.正反向代理 1.前提 我们曾经使用翻墙软件,访问google:使用了代理软件时,需要在浏览器选项中配置代理的地址,我们仅仅有代理这个概念,并不清楚代理还有正向和反向之分. 2.正向代理(代替客户端 ...

  4. Apache 强制SSL访问

    RewriteEngine On RewriteCond %{HTTPS} off RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R ...

  5. SCUT - 216 - 宝华科技树

    https://scut.online/p/216 演员 把这个当成dp算了半天,各种姿势,好吧,就当练习一下树dp. 假如是每个节点的层数之和,按照dp[i][j]为从i点出发获得j科技的最小费用d ...

  6. 安装最新版Elasticsearch报错

    1 问题:ERROR: bootstrap checks failed max file descriptors [4096] for elasticsearch process likely too ...

  7. [UWP]CompositionLinearGradientBrush加BlendEffect,双倍的快乐

    原文:[UWP]CompositionLinearGradientBrush加BlendEffect,双倍的快乐 1. 什么是BlendEffect# 上一篇文章介绍了CompositionLinea ...

  8. html5移动端Meta的设置

    强制让文档的宽度与设备的宽度保持1:1,并且文档最大的宽度比例是1.0,且不允许用户点击屏幕放大浏览 1 <meta name="viewport" content=&quo ...

  9. Hive配置日志

    1. 重命名hive/conf文件夹下的hive-log4j 2. 修改hive.log.dir参数,如果不修改默认hive.log位于/tmp/{user}下面,一般来说使用在hive目录下自己创建 ...

  10. tomcat 启动报错 解决办法 A child container failed during&nbsp

    转自:http://blog.sina.com.cn/s/blog_4e1e357d0102v55c.html 控制台报错: Caused by: org.apache.catalina.Lifecy ...