67 HTTP缓存及Nginx配置优化 - xiaoxin01/Blog GitHub Wiki
请求一个资源时,会得到的响应与缓存相关的有如下3种:
- 200
- 304 Not Modified
- 200 (from xxx cache)
第一次请求资源,或者资源过期时,会得到上面第1个响应,这种情况下,client会向Server发起一次请求。
非第一次请求资源,但资源超过了设置的缓存时间,并且自上次请求以后服务端没有修改,会得到上面第2个响应,这种情况下,client也会向Server发起一次请求。
非第一次请求资源,且资源没有超过设置的缓存时间,会得到上面第3个响应,这种情况下,client不会向Server发起请求。
如果要提升性能,尽可能的让资源返回第3种响应,其次第2种。
通过设置 Cache-Control(http/1.1)或 Expires(http/1.0),可以让浏览器在client端先进行过期验证而无需向Server发起请求。
比如某次请求,response header如下:
Cache-Control:max-age=15
Content-Type:text/css
Date:Tue, 24 Oct 2017 07:51:49 GMT
Expires:Tue, 24 Oct 2017 07:52:04 GMT
Last-Modified:Wed, 18 Oct 2017 01:23:11 GMT
表示该资源从 Date 表示的时间开始,有效时间为 15 秒,在client端时间小于 Date + 15 秒之前,再次访问该资源,浏览器会直接返回 200 (from xxx cache) 而不会向Server发送请求。
需要注意的是,Date为server返回的时间,如果server的时间和client时间不吻合,可能会导致client感知到的缓存有效时间与 max-age 声明的时间不同。
当资源超过了 200 (from xxx cache) 的有效期,再次请求该资源时,client会将 Last-Modified 的信息作为 Request Header的If-Modified_Since字段发送给Server,用于判断服务器的资源是否有变化,如果没有变化,则会返回 304 Not Modified
实际测试发现,Nginx启用gzip之后,即使原始资源没有改变, If-None-Match 和 If-Modified_Since 都没有变化,仍然会返回 200 而不是 304 Not Modified,可以通过去除ETag Header解决:
proxy_hide_header ETag;
另外的解决途径可能是通过 weak etag。
expires 15s;
做如上配置之后,Nginx会自动在response header生成 Cache-Control:max-age=15 和 Expires