前言
- 适用于云原生架构下的前端微服务,微服务内配置nginx.conf
- 适用于前端负责web nginx的相关配置
- 适用于想了解协商缓存的同学
缓存操作的目标
虽然 HTTP 缓存不是必须的,但重用缓存的资源通常是必要的。然而常见的 HTTP 缓存只能存储 GET
响应,对于其他类型的响应则无能为力。缓存的关键主要包括request method和目标URI(一般只有GET请求才会被缓存)。 普遍的缓存案例:
- 一个检索请求的成功响应: 对于
GET
请求,响应状态码为:200
,则表示为成功。一个包含例如HTML文档,图片,或者文件的响应。 - 永久重定向: 响应状态码:
301
。 - 错误响应: 响应状态码:
404
的一个页面。 - 不完全的响应: 响应状态码
206
,只返回局部的信息。 - 除了
GET
请求外,如果匹配到作为一个已被定义的cache键名的响应。
Cache-control
头
HTTP/1.1定义的 Cache-Control
头用来区分对缓存机制的支持情况, 请求头和响应头都支持这个属性。通过它提供的不同的值来定义缓存策略。
没有缓存
缓存中不得存储任何关于客户端请求和服务端响应的内容。每次由客户端发起的请求都会下载完整的响应内容。
Cache-Control: no-store
缓存但重新验证
如下头部定义,此方式下,每次有请求发出时,缓存会将此请求发到服务器(译者注:该请求应该会带有与本地缓存相关的验证字段),服务器端会验证请求中所描述的缓存是否过期,若未过期(注:实际就是返回304),则缓存才使用本地缓存副本。
Cache-Control: no-cache
私有和公共缓存
"public" 指令表示该响应可以被任何中间人(译者注:比如中间代理、CDN等)缓存。若指定了"public",则一些通常不被中间人缓存的页面(译者注:因为默认是private)(比如 带有HTTP验证信息(帐号密码)的页面 或 某些特定状态码的页面),将会被其缓存。
而 "private" 则表示该响应是专用于某单个用户的,中间人不能缓存此响应,该响应只能应用于浏览器私有缓存中。
Cache-Control: private
Cache-Control: public
过期
过期机制中,最重要的指令是 "max-age=<seconds>
",表示资源能够被缓存(保持新鲜)的最大时间。相对Expires而言,max-age是距离请求发起的时间的秒数。针对应用中那些不会改变的文件,通常可以手动设置一定的时长以保证缓存有效,例如图片、css、js等静态资源。
Cache-Control: max-age=31536000
验证方式
当使用了 "must-revalidate
" 指令,那就意味着缓存在考虑使用一个陈旧的资源时,必须先验证它的状态,已过期的缓存将不被使用。详情看下文关于缓存校验的内容。
Cache-Control: must-revalidate
Expires
Expires
响应头包含日期/时间, 即在此时候之后,响应过期。
无效的日期,比如 0, 代表着过去的日期,即该资源已经过期。
如果在Cache-Control
响应头设置了 "max-age" 或者 "s-max-age" 指令,那么 Expires
头会被忽略。
缓存验证
用户点击刷新按钮时会开始缓存验证。如果缓存的响应头信息里含有"Cache-control: must-revalidate”的定义,在浏览的过程中也会触发缓存验证。另外,在浏览器偏好设置里设置Advanced->Cache为强制验证缓存也能达到相同的效果。
当缓存的文档过期后,需要进行缓存验证或者重新获取资源。只有在服务器返回强校验器或者弱校验器时才会进行验证。
ETags
作为缓存的一种强校验器,ETag
响应头是一个对用户代理(User Agent, 下面简称UA)不透明(译者注:UA 无需理解,只需要按规定使用即可)的值。对于像浏览器这样的HTTP UA,不知道ETag代表什么,不能预测它的值是多少。如果资源请求的响应头里含有ETag, 客户端可以在后续的请求的头中带上 If-None-Match
头来验证缓存。
Last-Modified
响应头可以作为一种弱校验器。说它弱是因为它只能精确到一秒。如果响应头里含有这个信息,客户端可以在后续的请求中带上 If-Modified-Since
来验证缓存。
当向服务端发起缓存校验的请求时,服务端会返回 200
ok表示返回正常的结果或者 304
Not Modified(不返回body)表示浏览器可以使用本地缓存文件。304的响应头也可以同时更新缓存文档的过期时间。
强缓存
我们可以通过Expires
或者Cache-Control
来实现强缓存的设置
我们一般只需要设置html为强缓存-1就可以了
Cache-Control
server {
listen 8001;
server_name localhost;
+ add_header Cache-Control no-store;
location / {
...
}
...
}
Expires
server {
listen 8001;
server_name localhost;
+ expires -1;
location / {
...
}
...
}
协商缓存
我们可以通过Cache-Control
来实现强缓存的设置
我们可以通过以下方法,将html设置为协商缓存,js,css等静态资源,都设置表明可以被任何对象(包括:发送请求的客户端,代理服务器,等等)缓存
server {
listen 8001;
server_name localhost;
location / {
+ if ($request_uri ~* .*[.](js|css|map|jpg|png|svg|ico)$) {
+ #非html缓存1个月
+ add_header Cache-Control "public, max-age=2592000";
+ }
+ if ($request_filename ~* ^.*[.](html|htm)$) {
+ #html文件使用协商缓存
+ add_header Cache-Control "public, no-cache";
+ }
...
}
...
}
从下图可以看出,html每次都会去拿服务器最新的资源,js,css走了协商缓存