转载自: nginx 缓存配置

大家好, 我是 17。

和大家聊聊页面缓存 nginx 相关的配置。

http header 相关的缓存有两种

  1. 强制缓存
  2. 协商缓存

强制缓存

响应头部有两个值代表是否要强制缓存。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 offexpires -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