转载自: nginx 缓存配置
大家好, 我是 17。
和大家聊聊页面缓存 nginx 相关的配置。
http header 相关的缓存有两种
- 强制缓存
- 协商缓存
强制缓存
响应头部有两个值代表是否要强制缓存。Cache-Control 和 expires。至于为什么有两个头,expires 是历史遗留。
如果 不需要强制缓存 nginx可以这样配置
expires -1;
nginx 发回的头部
Cache-Control:no-cache
Expires:Thu, 18 Aug 2022 06:55:23 GMT
Expires 的时间比当前早一秒。
也可以不配置 nginx。 默认是关闭强制缓存的 expires off
expires off
和 expires -1
都可以关闭强制缓存,但响应头不一样,expires off
不会发送 Cache-Control 和 expires。
如果需要强制缓存 这样配置
expires 1d;
1d 表示强制缓存一天。但是浏览器是否采用强制缓存还取决于浏览器的具体实现。
比如你在浏览器中直接请求一个图片地址(网络上随便找张图片就成),查看响应头,一般都会带有 expires 和 Cache-control ,下次请求应该会命中强制缓存,但是,下次请求的时候走的是协商缓存,状态码是 304。为什么会这样呢?因为 chrome 在直接请求图片的时候 在请求头中加上了 cache-control:max-age=0
,表明本次请求不会采用强制缓存。
当强制刷新的时候,请求头 cache-control:no-cache
,响应码 200。浏览器忽略强制缓存,服务端忽略协商缓存,重新返回内容。
cache-control:no-cache
pragma:no-cache
不光是图片,chrome 直接访问 html 也不会命中强制缓存。对于浏览器的这个策略也是合理的。当访问一个网站的时候,我们第一个请求的是网站首页 index.html。如果首页被强制缓存了 10天,那么可能 10 天内用户看到的都是旧内容。
cache-control:no-store 这个字段就是告诉浏览器不进行缓存。这个最彻底,无论是强制缓存还是协商缓存都会关闭。nginx 中这样配置
add_header Cache-Control no-sotre;
cache-control:no-cache 关闭强制缓存,但还是会走协商缓存。
关闭了强制缓存就会走协商缓存,Last-Modified、etag, nginx 都会默认加上。
给图片等静态资源加强缓存
location ~* \.(?:css(\.map)?|js(\.map)?|gif|svg|jfif|ico|cur|heic|webp|tiff?|mp3|m4a|aac|ogg|midi?|wav|mp4|mov|webm|mpe?g|avi|ogv|flv|wmv)$ {
# 静态资源设置一年强缓存
expires 365d;
access_log off;
}
一般会给静态资源设置一个较长的缓存。如果资源发生变化,会修改文件名。一般用 md5 值做为文件名。
协商缓存
ETag
ETag HTTP 响应头是资源的特定版本的标识符。这可以让缓存更高效,并节省带宽,因为如果内容没有改变,Web 服务器不需要发送完整的响应。
ETag 头的一个典型用例是缓存未更改的资源。客户端就发送值为ETag的If-None-Match header 字段:
If-None-Match: “3378976f551425fcc55e4342u148795d9f25f89d4”
服务器将客户端的 ETag 与服务器相应资源当前版本的 ETag 进行比较,如果两个值匹配(即资源未更改),服务器将返回不带任何内容的304未修改状态,告诉客户端缓存版本可用(新鲜)。
Last-Modified
Etag 会消耗一定的服务器资源,Last-Modified 也可以用做缓存。
浏览器向服务端发送
if-modified-since: Fri, 24 Feb 2023 00:45:52 GMT
服务器收到请求后根据 if-modified-since 信息判断相关资源是否发生改变,如果没有改变,返回 304,不会发送具体内容到客户端。如果内容改变,发送 200 和内容。
不论怎样,服务器都会返回 Last-Modified 响应
Last-Modified: Thu, 23 Feb 2023 07:04:26 GMT