Edit

也说浏览器缓存

今天看到了一篇文章关于缓存和 Chrome 的“新版刷新" 然后在群里引为了关于浏览器缓存的讨论。 下面说一下浏览器缓存之我见

HTTP cache-control的策略

缓存可以降低网络请求,提升用户体验。所以对于一个有很好用户体验的客户端来讲,必然需要一定的缓存, 然而如何进行缓存,就需要有一定的缓存策略, (比如所有的资源全部5分钟内有效, 再如 所有资源全部都不进行缓存)。 对于浏览器,或者通用的webview 来讲, 因为不知道所要承载的资源,所以需要允许由不同的资源本身设置自己的缓存策略。 这就用到了HTTP的cache-control header。

浏览器(包含webview 下同)向server端请求一个资源时,比如a.html 同时在Response header 中可能会带有 Cache-Control的header, 浏览器将根据Cache-control 的内容,设着这个资源的缓存策略。 当然,如果没有Cache-Control字段,浏览器也可能有自己的一些默认行为, 这些默认行为将会随浏览器不同而不同。(比如firefox 默认的缓存策略是no-conrol, 而对于新版的chrome来讲,默认的缓存策略就变成了immutable

举个栗子

我们以请求 http://www.domob.cn/ 为例。

 ○ curl -v http://www.domob.cn
* Rebuilt URL to: http://www.domob.cn/
* Trying 124.250.50.9...
* TCP_NODELAY set
* Connected to www.domob.cn (124.250.50.9) port 80 (#0)
> GET / HTTP/1.1
> Host: www.domob.cn
> User-Agent: curl/7.51.0
> Accept: */*
>
< HTTP/1.1 200 OK
< Date: Thu, 23 Feb 2017 03:35:37 GMT
< Server: Apache
< Set-Cookie: PHPSESSID=r1gtnrhdkmqd1vnhilv8ndj3j3; path=/
< Expires: Thu, 19 Nov 1981 08:52:00 GMT
< Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
< Pragma: no-cache
< Transfer-Encoding: chunked
< Content-Type: text/html
<

对于这个资源来讲, Cache-Control的策略为 no-store, no-cache, must-revalidate, post-check=0, pre-check=0 然后浏览器就会根据server 端的返回来控制缓存

 ○ curl -v http://meirisuoping.com/index.html
* Trying 124.250.50.48...
* TCP_NODELAY set
* Connected to meirisuoping.com (124.250.50.48) port 80 (#0)
> GET /index.html HTTP/1.1
> Host: meirisuoping.com
> User-Agent: curl/7.51.0
> Accept: */*
>
< HTTP/1.1 200 OK
< Server: nginx/1.6.0
< Date: Thu, 23 Feb 2017 03:39:03 GMT
< Content-Type: text/html
< Content-Length: 4648
< Last-Modified: Fri, 22 Jul 2016 10:26:20 GMT
< Connection: close
< ETag: "5791f4cc-1228"
< Accept-Ranges: bytes

对于这个请求 服务端没有返回Cache-Control 这时浏览器可能会有自己的默认缓存策略。 对于不同的浏览器,对于不同的资源,缓存策略都是不同的。 这个稍后讨论。

不同的缓存策略

对于不同的caching 可以参看MDN文档 https://developer.mozilla.org/en-US/docs/Web/HTTP/Caching
以下是对这个文档的摘录

The Cache-Control HTTP/1.1 general-header field is used to specify directives for caching mechanisms in both requests and responses. Use this header to define your caching policies with the variety of directives it provides.

No cache storage at all

The cache should not store anything about the client request or server response. A request is sent to the server and a full response is downloaded each and every time.

Cache-Control: no-store
Cache-Control: no-cache, no-store, must-revalidate

No caching

A cache will send the request to the origin server for validation before releasing a cached copy.

Cache-Control: no-cache

Private and public caches

The “public" directive indicates that the response may be cached by any cache. This can be useful, if pages with HTTP authentication or response status codes that aren’t normally cacheable, should now be cached. On the other hand, “private" indicates that the response is intended for a single user only and must not be stored by a shared cache. A private browser cache may store the response in this case.

Cache-Control: private
Cache-Control: public

Expiration

The most important directive here is max-age= which is the maximum amount of time a resource will be considered fresh. Contrary to Expires, this directive is relative to the time of the request. For the files in the application that will not change, you can usually add aggressive caching. This includes static files such as images, CSS files and JavaScript files, for example.

Cache-Control: max-age=31536000

Validation

When using the “must-revalidate" directive, the cache must verify the status of the stale resources before using it and expired ones should not be used. For more details, see the Validation section below.

Cache-Control: must-revalidate

缓存的刷新策略

对于一个资源来说, 可以Cache再浏览器内,浏览器Cache的资源有两种状态, 未过期的资源 fresh 和已经过期的资源 stale 。当浏览器请求stale的资源时, 浏览器将向server端发送一个资源验证请求, 服务端根据浏览器的请求返回304 或者是200
如下图

缓存刷新策略

资源验证请求

当Server端返回的资源有Etag或者Last-Modified头时,浏览器会在资源stale的时候, 向服务端重新发送请求。当服务端认为资源可以继续用的时候就返回304, 当服务端认为资源不可再用的时候就要返回 200 加资源。

Alt text

生产环境中的具体使用

在生产环境中, 我们当然希望资源cache的越多越好, 但是又希望资源能在我们需要过期的时候立即过期。

对于css,js, 或图片文件来讲, 我们可以用webpack之类的前端工具,对css文件, js文件,命名成hash值的形式, 这样就可以一直缓存在浏览器端, 当发布新资源的时候, hash值改变了, 浏览器就会立即更新过来。

但对于 index.html 这样的文件, 我们就不能一直缓存, 对于这种文件有两种处理方式,

  1. 缓存可接受的时间 如 5分钟
  2. 将缓存策略设置为 no-cache

因为不同浏览器或webview对于不设着缓存策略的资源有着不同甚至比较诡异的行为,所以为了保险起见,一定要设着Cache-Control

最后以夺宝吧的nginx配置为例,仅供参考


# 静态图片缓存30天
location ~ .*\.(gif|jpg|jpeg|png|bmp|swf)$ {
expires 30d;
add_header Cache-Control "public";

}


# h5资源缓存30分钟
# 因为对于夺宝来说css,js没有取hash值, 所以就缓存一个可接受的时间范围。
location ~ ^/(html|js|css) {
expires 30m;
add_header Cache-Control "public";
}

%23%u4E5F%u8BF4%u6D4F%u89C8%u5668%u7F13%u5B58%0A@%28tech%29%5Bpublished%5D%0A%0A%u4ECA%u5929%u770B%u5230%u4E86%u4E00%u7BC7%u6587%u7AE0%5B%u5173%u4E8E%u7F13%u5B58%u548C%20Chrome%20%u7684%u201C%u65B0%u7248%u5237%u65B0%u201D%5D%28http%3A//www.cnblogs.com/ziyunfei/p/6308652.html%29%20%u7136%u540E%u5728%u7FA4%u91CC%u5F15%u4E3A%u4E86%u5173%u4E8E%u6D4F%u89C8%u5668%u7F13%u5B58%u7684%u8BA8%u8BBA%u3002%20%u4E0B%u9762%u8BF4%u4E00%u4E0B%u6D4F%u89C8%u5668%u7F13%u5B58%u4E4B%u6211%u89C1%0A%0A%23%23%20HTTP%20cache-control%u7684%u7B56%u7565%0A%0A%u7F13%u5B58%u53EF%u4EE5%u964D%u4F4E%u7F51%u7EDC%u8BF7%u6C42%uFF0C%u63D0%u5347%u7528%u6237%u4F53%u9A8C%u3002%u6240%u4EE5%u5BF9%u4E8E%u4E00%u4E2A%u6709%u5F88%u597D%u7528%u6237%u4F53%u9A8C%u7684%u5BA2%u6237%u7AEF%u6765%u8BB2%uFF0C%u5FC5%u7136%u9700%u8981%u4E00%u5B9A%u7684%u7F13%u5B58%uFF0C%20%u7136%u800C%u5982%u4F55%u8FDB%u884C%u7F13%u5B58%uFF0C%u5C31%u9700%u8981%u6709%u4E00%u5B9A%u7684**%u7F13%u5B58%u7B56%u7565**%uFF0C%20%uFF08%u6BD4%u5982%u6240%u6709%u7684%u8D44%u6E90%u5168%u90E85%u5206%u949F%u5185%u6709%u6548%uFF0C%20%u518D%u5982%20%u6240%u6709%u8D44%u6E90%u5168%u90E8%u90FD%u4E0D%u8FDB%u884C%u7F13%u5B58%uFF09%u3002%20%u5BF9%u4E8E%u6D4F%u89C8%u5668%uFF0C%u6216%u8005%u901A%u7528%u7684webview%20%u6765%u8BB2%uFF0C%20%u56E0%u4E3A%u4E0D%u77E5%u9053%u6240%u8981%u627F%u8F7D%u7684%u8D44%u6E90%uFF0C%u6240%u4EE5%u9700%u8981%u5141%u8BB8%u7531%u4E0D%u540C%u7684%u8D44%u6E90%u672C%u8EAB%u8BBE%u7F6E%u81EA%u5DF1%u7684%u7F13%u5B58%u7B56%u7565%u3002%20%u8FD9%u5C31%u7528%u5230%u4E86HTTP%u7684cache-control%20header%u3002%0A%0A%u6D4F%u89C8%u5668%uFF08%u5305%u542Bwebview%20%u4E0B%u540C%uFF09%u5411server%u7AEF%u8BF7%u6C42%u4E00%u4E2A%u8D44%u6E90%u65F6%uFF0C%u6BD4%u5982%60a.html%60%20%u540C%u65F6%u5728Response%20header%20%u4E2D%u53EF%u80FD%u4F1A%u5E26%u6709%20%60Cache-Control%60%u7684header%uFF0C%20%u6D4F%u89C8%u5668%u5C06%u6839%u636E%60Cache-control%60%20%u7684%u5185%u5BB9%uFF0C%u8BBE%u7740%u8FD9%u4E2A%u8D44%u6E90%u7684%u7F13%u5B58%u7B56%u7565%u3002%20%u5F53%u7136%uFF0C%u5982%u679C%u6CA1%u6709%60Cache-Control%60%u5B57%u6BB5%uFF0C%u6D4F%u89C8%u5668%u4E5F%u53EF%u80FD%u6709%u81EA%u5DF1%u7684%u4E00%u4E9B%u9ED8%u8BA4%u884C%u4E3A%uFF0C%20%u8FD9%u4E9B%u9ED8%u8BA4%u884C%u4E3A%u5C06%u4F1A%u968F%u6D4F%u89C8%u5668%u4E0D%u540C%u800C%u4E0D%u540C%u3002%uFF08%u6BD4%u5982firefox%20%u9ED8%u8BA4%u7684%u7F13%u5B58%u7B56%u7565%u662F%60no-conrol%60%2C%20%u800C%u5BF9%u4E8E%u65B0%u7248%u7684chrome%u6765%u8BB2%uFF0C%u9ED8%u8BA4%u7684%u7F13%u5B58%u7B56%u7565%u5C31%u53D8%u6210%u4E86%60immutable%60%uFF09%0A%0A%0A%23%23%23%20%u4E3E%u4E2A%u6817%u5B50%0A%0A%u6211%u4EEC%u4EE5%u8BF7%u6C42%20%60http%3A//www.domob.cn/%60%20%u4E3A%u4F8B%u3002%0A%0A%60%60%60bash%0A%20%u25CB%20curl%20-v%20http%3A//www.domob.cn%0A*%20Rebuilt%20URL%20to%3A%20http%3A//www.domob.cn/%0A*%20%20%20Trying%20124.250.50.9...%0A*%20TCP_NODELAY%20set%0A*%20Connected%20to%20www.domob.cn%20%28124.250.50.9%29%20port%2080%20%28%230%29%0A%3E%20GET%20/%20HTTP/1.1%0A%3E%20Host%3A%20www.domob.cn%0A%3E%20User-Agent%3A%20curl/7.51.0%0A%3E%20Accept%3A%20*/*%0A%3E%0A%3C%20HTTP/1.1%20200%20OK%0A%3C%20Date%3A%20Thu%2C%2023%20Feb%202017%2003%3A35%3A37%20GMT%0A%3C%20Server%3A%20Apache%0A%3C%20Set-Cookie%3A%20PHPSESSID%3Dr1gtnrhdkmqd1vnhilv8ndj3j3%3B%20path%3D/%0A%3C%20Expires%3A%20Thu%2C%2019%20Nov%201981%2008%3A52%3A00%20GMT%0A%3C%20Cache-Control%3A%20no-store%2C%20no-cache%2C%20must-revalidate%2C%20post-check%3D0%2C%20pre-check%3D0%0A%3C%20Pragma%3A%20no-cache%0A%3C%20Transfer-Encoding%3A%20chunked%0A%3C%20Content-Type%3A%20text/html%0A%3C%0A%0A%60%60%60%0A%u5BF9%u4E8E%u8FD9%u4E2A%u8D44%u6E90%u6765%u8BB2%uFF0C%20Cache-Control%u7684%u7B56%u7565%u4E3A%20%60no-store%2C%20no-cache%2C%20must-revalidate%2C%20post-check%3D0%2C%20pre-check%3D0%60%20%u7136%u540E%u6D4F%u89C8%u5668%u5C31%u4F1A%u6839%u636Eserver%20%u7AEF%u7684%u8FD4%u56DE%u6765%u63A7%u5236%u7F13%u5B58%0A%0A%60%60%60bash%0A%20%u25CB%20curl%20-v%20http%3A//meirisuoping.com/index.html%0A*%20%20%20Trying%20124.250.50.48...%0A*%20TCP_NODELAY%20set%0A*%20Connected%20to%20meirisuoping.com%20%28124.250.50.48%29%20port%2080%20%28%230%29%0A%3E%20GET%20/index.html%20HTTP/1.1%0A%3E%20Host%3A%20meirisuoping.com%0A%3E%20User-Agent%3A%20curl/7.51.0%0A%3E%20Accept%3A%20*/*%0A%3E%0A%3C%20HTTP/1.1%20200%20OK%0A%3C%20Server%3A%20nginx/1.6.0%0A%3C%20Date%3A%20Thu%2C%2023%20Feb%202017%2003%3A39%3A03%20GMT%0A%3C%20Content-Type%3A%20text/html%0A%3C%20Content-Length%3A%204648%0A%3C%20Last-Modified%3A%20Fri%2C%2022%20Jul%202016%2010%3A26%3A20%20GMT%0A%3C%20Connection%3A%20close%0A%3C%20ETag%3A%20%225791f4cc-1228%22%0A%3C%20Accept-Ranges%3A%20bytes%0A%60%60%60%0A%0A%u5BF9%u4E8E%u8FD9%u4E2A%u8BF7%u6C42%20%u670D%u52A1%u7AEF%u6CA1%u6709%u8FD4%u56DECache-Control%20%u8FD9%u65F6%u6D4F%u89C8%u5668%u53EF%u80FD%u4F1A%u6709%u81EA%u5DF1%u7684%u9ED8%u8BA4%u7F13%u5B58%u7B56%u7565%u3002%20%u5BF9%u4E8E%u4E0D%u540C%u7684%u6D4F%u89C8%u5668%uFF0C%u5BF9%u4E8E%u4E0D%u540C%u7684%u8D44%u6E90%uFF0C%u7F13%u5B58%u7B56%u7565%u90FD%u662F%u4E0D%u540C%u7684%u3002%20%u8FD9%u4E2A%u7A0D%u540E%u8BA8%u8BBA%u3002%0A%0A%23%23%23%20%u4E0D%u540C%u7684%u7F13%u5B58%u7B56%u7565%0A%u5BF9%u4E8E%u4E0D%u540C%u7684caching%20%u53EF%u4EE5%u53C2%u770BMDN%u6587%u6863%20https%3A//developer.mozilla.org/en-US/docs/Web/HTTP/Caching%0A%u4EE5%u4E0B%u662F%u5BF9%u8FD9%u4E2A%u6587%u6863%u7684%u6458%u5F55%0A%0AThe%20Cache-Control%20HTTP/1.1%20general-header%20field%20is%20used%20to%20specify%20directives%20for%20caching%20mechanisms%20in%20both%20requests%20and%20responses.%20Use%20this%20header%20to%20define%20your%20caching%20policies%20with%20the%20variety%20of%20directives%20it%20provides.%0A%0A%23%23%23%23%20No%20cache%20storage%20at%20all%0A%0AThe%20cache%20should%20not%20store%20anything%20about%20the%20client%20request%20or%20server%20response.%20A%20request%20is%20sent%20to%20the%20server%20and%20a%20full%20response%20is%20downloaded%20each%20and%20every%20time.%0A%0A%60%60%60http%0ACache-Control%3A%20no-store%0ACache-Control%3A%20no-cache%2C%20no-store%2C%20must-revalidate%0A%60%60%60%0A%0A%23%23%23%23%20No%20caching%0AA%20cache%20will%20send%20the%20request%20to%20the%20origin%20server%20for%20validation%20before%20releasing%20a%20cached%20copy.%0A%0A%60%60%60http%0ACache-Control%3A%20no-cache%0A%60%60%60%0A%0A%23%23%23%23%20Private%20and%20public%20caches%0A%0AThe%20%22public%22%20directive%20indicates%20that%20the%20response%20may%20be%20cached%20by%20any%20cache.%20This%20can%20be%20useful%2C%20if%20pages%20with%20HTTP%20authentication%20or%20response%20status%20codes%20that%20aren%27t%20normally%20cacheable%2C%20should%20now%20be%20cached.%20On%20the%20other%20hand%2C%20%22private%22%20indicates%20that%20the%20response%20is%20intended%20for%20a%20single%20user%20only%20and%20must%20not%20be%20stored%20by%20a%20shared%20cache.%20A%20private%20browser%20cache%20may%20store%20the%20response%20in%20this%20case.%0A%0A%60%60%60http%0ACache-Control%3A%20private%0ACache-Control%3A%20public%0A%60%60%60%0A%0A%23%23%23%23Expiration%0A%0AThe%20most%20important%20directive%20here%20is%20%60max-age%3D%3Cseconds%3E%60%20which%20is%20the%20maximum%20amount%20of%20time%20a%20resource%20will%20be%20considered%20fresh.%20Contrary%20to%20Expires%2C%20this%20directive%20is%20relative%20to%20the%20time%20of%20the%20request.%20For%20the%20files%20in%20the%20application%20that%20will%20not%20change%2C%20you%20can%20usually%20add%20aggressive%20caching.%20This%20includes%20static%20files%20such%20as%20images%2C%20CSS%20files%20and%20JavaScript%20files%2C%20for%20example.%0A%0A%0A%60%60%60http%0ACache-Control%3A%20max-age%3D31536000%0A%60%60%60%0A%23%23%23%23%20Validation%0A%0AWhen%20using%20the%20%22must-revalidate%22%20directive%2C%20the%20cache%20must%20verify%20the%20status%20of%20the%20stale%20resources%20before%20using%20it%20and%20expired%20ones%20should%20not%20be%20used.%20For%20more%20details%2C%20see%20the%20Validation%20section%20below.%0A%0A%60%60%60http%0ACache-Control%3A%20must-revalidate%0A%60%60%60%0A%0A%23%23%23%20%u7F13%u5B58%u7684%u5237%u65B0%u7B56%u7565%0A%0A%u5BF9%u4E8E%u4E00%u4E2A%u8D44%u6E90%u6765%u8BF4%uFF0C%20%u53EF%u4EE5Cache%u518D%u6D4F%u89C8%u5668%u5185%uFF0C%u6D4F%u89C8%u5668Cache%u7684%u8D44%u6E90%u6709%u4E24%u79CD%u72B6%u6001%uFF0C%20%u672A%u8FC7%u671F%u7684%u8D44%u6E90%20**fresh**%20%u548C%u5DF2%u7ECF%u8FC7%u671F%u7684%u8D44%u6E90%20**stale**%20%u3002%u5F53%u6D4F%u89C8%u5668%u8BF7%u6C42**stale**%u7684%u8D44%u6E90%u65F6%uFF0C%20%u6D4F%u89C8%u5668%u5C06%u5411server%u7AEF%u53D1%u9001%u4E00%u4E2A%u8D44%u6E90%u9A8C%u8BC1%u8BF7%u6C42%uFF0C%20%u670D%u52A1%u7AEF%u6839%u636E%u6D4F%u89C8%u5668%u7684%u8BF7%u6C42%u8FD4%u56DE%60304%60%20%u6216%u8005%u662F%60200%60%u3002%20%0A%u5982%u4E0B%u56FE%0A%21%5B%u7F13%u5B58%u5237%u65B0%u7B56%u7565%5D%28https%3A//mdn.mozillademos.org/files/13771/HTTPStaleness.png%29%0A%0A%23%23%23%23%20%u8D44%u6E90%u9A8C%u8BC1%u8BF7%u6C42%0A%0A%u5F53Server%u7AEF%u8FD4%u56DE%u7684%u8D44%u6E90%u6709%60Etag%60%u6216%u8005%60%20Last-Modified%60%u5934%u65F6%uFF0C%u6D4F%u89C8%u5668%u4F1A%u5728%u8D44%u6E90%60stale%60%u7684%u65F6%u5019%uFF0C%20%u5411%u670D%u52A1%u7AEF%u91CD%u65B0%u53D1%u9001%u8BF7%u6C42%u3002%u5F53%u670D%u52A1%u7AEF%u8BA4%u4E3A%u8D44%u6E90%u53EF%u4EE5%u7EE7%u7EED%u7528%u7684%u65F6%u5019%u5C31%u8FD4%u56DE304%uFF0C%20%u5F53%u670D%u52A1%u7AEF%u8BA4%u4E3A%u8D44%u6E90%u4E0D%u53EF%u518D%u7528%u7684%u65F6%u5019%u5C31%u8981%u8FD4%u56DE%20200%20%u52A0%u8D44%u6E90%u3002%0A%0A%21%5BAlt%20text%5D%281487839641923.png%29%0A%0A%23%23%20%u751F%u4EA7%u73AF%u5883%u4E2D%u7684%u5177%u4F53%u4F7F%u7528%0A%0A%u5728%u751F%u4EA7%u73AF%u5883%u4E2D%uFF0C%20%u6211%u4EEC%u5F53%u7136%u5E0C%u671B%u8D44%u6E90cache%u7684%u8D8A%u591A%u8D8A%u597D%uFF0C%20%u4F46%u662F%u53C8%u5E0C%u671B%u8D44%u6E90%u80FD%u5728%u6211%u4EEC%u9700%u8981%u8FC7%u671F%u7684%u65F6%u5019%u7ACB%u5373%u8FC7%u671F%u3002%20%0A%0A%u5BF9%u4E8Ecss%uFF0Cjs%uFF0C%20%u6216%u56FE%u7247%u6587%u4EF6%u6765%u8BB2%uFF0C%20%u6211%u4EEC%u53EF%u4EE5%u7528webpack%u4E4B%u7C7B%u7684%u524D%u7AEF%u5DE5%u5177%uFF0C%u5BF9css%u6587%u4EF6%uFF0C%20js%u6587%u4EF6%uFF0C%u547D%u540D%u6210hash%u503C%u7684%u5F62%u5F0F%uFF0C%20%u8FD9%u6837%u5C31%u53EF%u4EE5%u4E00%u76F4%u7F13%u5B58%u5728%u6D4F%u89C8%u5668%u7AEF%uFF0C%20%u5F53%u53D1%u5E03%u65B0%u8D44%u6E90%u7684%u65F6%u5019%uFF0C%20hash%u503C%u6539%u53D8%u4E86%uFF0C%20%u6D4F%u89C8%u5668%u5C31%u4F1A%u7ACB%u5373%u66F4%u65B0%u8FC7%u6765%u3002%0A%0A%u4F46%u5BF9%u4E8E%20%60index.html%60%20%u8FD9%u6837%u7684%u6587%u4EF6%uFF0C%20%u6211%u4EEC%u5C31%u4E0D%u80FD%u4E00%u76F4%u7F13%u5B58%uFF0C%20%u5BF9%u4E8E%u8FD9%u79CD%u6587%u4EF6%u6709%u4E24%u79CD%u5904%u7406%u65B9%u5F0F%uFF0C%20%0A1.%20%u7F13%u5B58%u53EF%u63A5%u53D7%u7684%u65F6%u95F4%20%u5982%205%u5206%u949F%0A2.%20%u5C06%u7F13%u5B58%u7B56%u7565%u8BBE%u7F6E%u4E3A%20no-cache%20%0A%0A**%u56E0%u4E3A%u4E0D%u540C%u6D4F%u89C8%u5668%u6216webview%u5BF9%u4E8E%u4E0D%u8BBE%u7740%u7F13%u5B58%u7B56%u7565%u7684%u8D44%u6E90%u6709%u7740%u4E0D%u540C%u751A%u81F3%u6BD4%u8F83%u8BE1%u5F02%u7684%u884C%u4E3A%uFF0C%u6240%u4EE5%u4E3A%u4E86%u4FDD%u9669%u8D77%u89C1%uFF0C%u4E00%u5B9A%u8981%u8BBE%u7740Cache-Control**%0A%0A%u6700%u540E%u4EE5%u593A%u5B9D%u5427%u7684nginx%u914D%u7F6E%u4E3A%u4F8B%uFF0C%u4EC5%u4F9B%u53C2%u8003%0A%0A%60%60%60nginx%0A%20%20%20%20%0A%20%20%20%20%23%20%u9759%u6001%u56FE%u7247%u7F13%u5B5830%u5929%0A%20%20%20%20location%20%20%7E%20.*%5C.%28gif%7Cjpg%7Cjpeg%7Cpng%7Cbmp%7Cswf%29%24%20%7B%0A%20%20%20%20%09expires%2030d%3B%0A%09add_header%20Cache-Control%20%22public%22%3B%0A%0A%20%20%20%20%7D%0A%0A%0A%20%20%20%20%23%20h5%u8D44%u6E90%u7F13%u5B5830%u5206%u949F%0A%20%20%20%20%23%20%u56E0%u4E3A%u5BF9%u4E8E%u593A%u5B9D%u6765%u8BF4css%2Cjs%u6CA1%u6709%u53D6hash%u503C%uFF0C%20%u6240%u4EE5%u5C31%u7F13%u5B58%u4E00%u4E2A%u53EF%u63A5%u53D7%u7684%u65F6%u95F4%u8303%u56F4%u3002%0A%20%20%20%20location%20%7E%20%5E/%28html%7Cjs%7Ccss%29%20%7B%0A%20%20%20%20%09expires%2030m%3B%0A%20%20%20%20%20%20%20%20add_header%20Cache-Control%20%22public%22%3B%0A%20%20%20%20%7D%0A%0A%60%60%60