本文由 简悦 SimpRead 转码, 原文地址 www.cnblogs.com

来源:利用nginx设置浏览器协商缓存 - debugger.wiki - debugger.wiki 用途:备忘 强缓存与协商缓存的区别 强缓存:浏览器不与服务端协商直接取浏览器缓存 协商缓存:浏览

来源:利用 nginx 设置浏览器协商缓存 - debugger.wiki - debugger.wiki

用途:备忘

强缓存与协商缓存的区别

  强缓存:浏览器不与服务端协商直接取浏览器缓存

  协商缓存:浏览器会先向服务器确认资源的有效性后才决定是从缓存中取资源还是重新获取资源

协商缓存运作原理

  现在有一个这样的业务情景:后端的静态资源会不定时地发生更新,而因为浏览器默认使用强缓存,会默认从浏览器缓存中取到过时的资源。

  现在我们希望浏览器每次获取资源的时候都向后端确认资源是否更新,就要设置浏览器使用协商缓存

  那么后端如何判断资源是否更新了呢?这时就要用到 Etag 和 Last-Modified 两项响应头。

  每次收到一个静态资源的请求时,后端都将资源的最后修改时间(Last-Modified)、根据资源内容计算出来的 Etag 放在响应头给前端。

  前端收到响应后将这两项缓存起来,然后在下次请求同样资源的时候,将这两项的内容放到 If-Modified-Since 和 If-None-Match 这两项请求头中。

  服务端收到这两项后,会与资源当前生成的 Etag 和 Last-Modified 做比较,如果两者都一致,说明资源没有更新,服务端会返回 304 空响应;否则,说明资源有更新,服务端会将完整的资源内容返回

实现

  那么如何实现这样一个复杂的过程呢?其实很简单,只要使用 nginx 作为静态资源的服务器,再在响应头加上 Cache-Control:no-cache 就可以了。

  下面来分步骤实现一下

  1.  使用 nginx 作为静态资源的服务器

    在 nginx 的配置中,将对静态资源的请求映射到资源的磁盘路径上

 1 http {
 2     server {
 3     listen 80;
 4     ...
 5     location /picture/ {
 6         alias D:/luozixi/tcp_test/picture/;
 7         # alias是重定义路径
 8         # 比如访问127.0.0.1/picture/1_new.gif,则会映射为访问D:/luozixi/tcp_test/picture/1_new.gif
 9         # web应用根本不会收到请求,picture的请求都被nginx处理了
10         # alias是替换,root是拼接
11         autoindex on;
12         # 访问127.0.0.1/picture/,会得到目录的索引界面
13         }
14     }
15 }    

  2.  重新加载 nginx 配置

nginx -s reload

  3.  此时,请求静态资源的时候 nginx 会自动在 response 头中加上 Etag 和 Last-Modified 两项

   

  4.  但是这时发现,如果不配置 Cache-Contrl: no-cache,浏览器在下次请求这个资源的时候不会将请求发向后端,而是直接从缓存中获取资源

  5. 在 nginx 中配置

location /picture/ { 
    add_header Cache-Control no-cache;
    alias D:/luozixi/tcp_test/picture/; 
}  

  6. 清除浏览器缓存后第一次发起请求,会得到一个正常的 200 Response,而且响应头里已经有了 Cache-Control: no-cache,表示使用协商缓存

  7.  再次发起请求后,会发现请求头已经带上了 If-Modified-Since 和 If-None-Match 两项

  

  8.  服务端(nginx)收到这两项后,会与资源当前生成的 Etag 和 Last-Modified 做比较,如果两者都一致,说明资源没有更新,服务端会返回 304 空响应;否则,说明资源有更新,服务端会将完整的资源内容返回

    另外,服务器验证 If-Modified-Since 的方式只是简单的字符串比较,即使资源的 Last-Modified 比 If-Modified-Since 要早,服务端仍认为资源有更新

  9. 浏览器在收到 304 响应后,会从浏览器缓存中取资源。因此速度非常块

  

no-cache 与 no-store 的区别

  no-cache 表示不缓存过期资源,缓存会向服务器进行有效处理确认之后处理资源

  而 no-store 才是真正的不进行缓存。