什么是缓存控制:私有?

use*_*220 138 caching http cache-control browser-cache http-headers

当我访问chesseng.herokuapp.com时,我得到一个看起来像的响应头

Cache-Control:private
Connection:keep-alive
Content-Encoding:gzip
Content-Type:text/css
Date:Tue, 16 Oct 2012 06:37:53 GMT
Last-Modified:Tue, 16 Oct 2012 03:13:38 GMT
Status:200 OK
transfer-encoding:chunked
Vary:Accept-Encoding
X-Rack-Cache:miss
Run Code Online (Sandbox Code Playgroud)

然后我刷新页面然后得到

Cache-Control:private
Connection:keep-alive
Date:Tue, 16 Oct 2012 06:20:49 GMT
Status:304 Not Modified
X-Rack-Cache:miss
Run Code Online (Sandbox Code Playgroud)

所以看起来缓存工作正常.如果它适用于缓存,则ExpiresCache-Control的重点是:max-age.更令人困惑的是,当我在https://developers.google.com/speed/pagespeed/insights/上测试该页面时,它告诉我"利用浏览器缓存".

Dan*_* D. 163

Cache-Control: private
Run Code Online (Sandbox Code Playgroud)

指示响应消息的全部或部分是针对单个用户的,并且不得由共享高速缓存(例如代理服务器)进行高速缓存.

来自RFC2616第14.9.1节

  • 因为它是由您的浏览器缓存的.您是响应所针对的单个用户. (14认同)
  • 不,这不是因为`Cache-Control:private`仅表明共享缓存(例如代理缓存)不应该缓存响应. (13认同)
  • @Trejkaz不,它真的意味着一个用户.用户是具有其自己的主目录的帐户,缓存驻留在该目录中.由同一用户拥有的那些配置文件可以共享其缓存.正如你所发现的那样.但是,如果由不同用户拥有,则同一计算机上的两个配置文件不得共享其缓存,除非该缓存被视为共享缓存. (4认同)
  • 啊,所以它是每个用户在操作系统级别。是的,我想知道的原因是因为 Chrome 的隐身窗口和非隐身窗口之间存在明显的信息泄漏,后者使用缓存来做到这一点。 (2认同)
  • @didibus`proxy-revalidate`要求代理始终在每次访问时重新验证."private"阻止代理缓存的地方. (2认同)

Ian*_*oyd 57

要回答有关缓存工作原因的问题,即使Web服务器未包含标头:

  • 过期: [a date]
  • 缓存控制: max-age =[seconds]

服务器请求任何中间代理不缓存内容(即该项只应缓存在私有缓存中,即仅在您自己的本地机器上):

  • 缓存控制:私有

但服务器忘记包含任何类型的缓存提示:

  • 他们忘了包含Expires,因此浏览器知道在该日期之前使用缓存副本
  • 他们忘了包含Max-Age,因此浏览器知道缓存项目有多长时间
  • 他们忘了包含E-Tag,因此浏览器可以执行条件请求

但他们确实在响应中包含了 Last-Modified日期:

Last-Modified: Tue, 16 Oct 2012 03:13:38 GMT
Run Code Online (Sandbox Code Playgroud)

因为浏览器知道文件被修改的日期,所以它可以执行条件请求.它会向服务器询问该文件,但是如果自2012/10/16 3:13:38以来修改了文件,则指示服务器仅发送该文件:

GET / HTTP/1.1
If-Modified-Since: Tue, 16 Oct 2012 03:13:38 GMT
Run Code Online (Sandbox Code Playgroud)

服务器接收请求,意识到客户端已经具有最新版本.而不是发送客户端200 OK,然后是页面的内容,而是告诉您缓存的版本是好的:

304 Not Modified
Run Code Online (Sandbox Code Playgroud)

您的浏览器确实不得不延迟向服务器发送请求,并等待响应,但它确实无需重新下载静态内容.

为何选择Max-Age?为何过期

因为Last-Modified很糟糕.

在服务器上不是每件事都有与之相关联的日期.如果我正在动态构建页面,则没有与之关联的日期 - 现在就是这样.但我完全愿意让用户缓存主页15秒:

200 OK
Cache-Control: max-age=15
Run Code Online (Sandbox Code Playgroud)

如果用户敲击F5,他们将继续获得缓存版本15秒.如果它是公司代理,那么在同一个15秒窗口中访问同一页面的所有67198用户都将获得相同的内容 - 所有这些用户都是从关闭缓存中提供的.每个人的表现都很棒.

添加的优点Cache-Control: max-age是浏览器甚至不必执行条件请求.

  • 如果您只是指定Last-Modified,浏览器必须执行请求If-Modified-Since,并注意304 Not Modified响应
  • 如果你指定max-age,浏览器甚至不必遭受网络往返; 内容将来自缓存

"Cache-Control:max-age"和"Expires"之间的区别

Expires是现代(c.1998)Cache-Control: max-age标题的遗留等价物:

  • Expires:你指定一个日期(yuck)
  • max-age:你指定秒(善良)
  • 如果两者都已指定,则浏览器使用max-age:

    200 OK
    Cache-Control: max-age=60
    Expires: 20180403T192837 
    
    Run Code Online (Sandbox Code Playgroud)

1998年以后写的任何网站都不应再使用Expires,而是使用max-age.

什么是ETag?

ETag类似于Last-Modified,除了它不必是一个日期 - 它只需要是一个东西.

如果我从数据库中提取产品列表,服务器可以将最后一个rowversion作为ETag 发送,而不是日期:

200 OK
ETag: "247986"
Run Code Online (Sandbox Code Playgroud)

我的ETag可以是静态资源(例如图像,js,css,字体)或缓存的渲染页面的SHA1哈希值(即这是Mozilla MDN wiki所做的;它们对最终标记进行哈希):

200 OK
ETag: "33a64df551425fcc55e4d42a148795d9f25f89d4"
Run Code Online (Sandbox Code Playgroud)

与基于Last-Modified的条件请求完全相同:

GET / HTTP/1.1
If-Modified-Since: Tue, 16 Oct 2012 03:13:38 GMT

304 Not Modified
Run Code Online (Sandbox Code Playgroud)

我可以根据ETag 执行条件请求:

GET / HTTP/1.1
If-None-Match: "33a64df551425fcc55e4d42a148795d9f25f89d4"

304 Not Modified
Run Code Online (Sandbox Code Playgroud)

一个ETag优于Last-Modified它,因为它适用于文件之外的东西,或具有日期概念的东西.它就是


Pau*_*per 20

RFC 2616,第14.9.1节:

指示响应消息的全部或部分是针对单个用户的,并且不得由共享缓存缓存...私有(非共享)缓存可以缓存响应.


浏览器可以使用此信息.当然,当前的"用户"可能意味着很多东西:操作系统用户,浏览器用户(例如Chrome的配置文件)等.它没有指定.

对我来说,更具体的例子Cache-Control: private是,代理服务器(通常有许多用户)将不缓存它.它适用于最终用户,而不是其他任何人.


仅供参考,RFC明确指出这不提供安全性.它是关于显示正确的内容,而不是保护内容.

单词private的这种用法仅控制可以缓存响应的位置,并且不能确保消息内容的隐私.

  • **私有(非共享)缓存可以缓存响应.**这部分是关键.谢谢. (5认同)