考虑我的EC2实例,其内容应始终具有五分钟的生命周期.对于静态内容,这通常意味着在我的web.config文件中声明以下内容:
<staticContent> <clientCache cacheControlCustom="public" cacheControlMode="UseMaxAge" cacheControlMaxAge="00.00:05:00"/> </staticContent>
…对于动态内容,它通常意味着对HttpResponse对象执行以下命令:
resp.Cache.SetCacheability(HttpCacheability.Public); resp.Cache.SetMaxAge(TimeSpan.FromMinutes(5));
以此为背景……
当我的浏览器直接点击ELB时,一切都按预期工作. Firebug始终显示,对于存在于浏览器缓存中的内容,已返回304(未修改),已超过五分钟到期,但尚未在服务器上更改.以下是defs.js下载的响应标头,例如:
HTTP/1.1 304 Not Modified Accept-Ranges: bytes Cache-Control: public,max-age=300 Date: Tue,22 Apr 2014 13:54:16 GMT Etag: "0152435d158cf1:0" Last-Modified: Tue,15 Apr 2014 17:36:18 GMT Server: Microsoft-IIS/7.5 X-Powered-By: ASP.NET Connection: keep-alive
IIS正确地看到该文件自4月15日以来未被更改并返回304.
HTTP/1.1 200 OK Content-Type: application/x-javascript Content-Length: 205 Connection: keep-alive Accept-Ranges: bytes Cache-Control: public,22 Apr 2014 14:07:33 GMT Etag: "0152435d158cf1:0" Last-Modified: Tue,15 Apr 2014 17:36:18 GMT Server: Microsoft-IIS/7.5 X-Powered-By: ASP.NET Age: 16 X-Cache: Hit from cloudfront Via: 1.1 0f140ef1be762325ad24a7167aa57e65.cloudfront.net (CloudFront) X-Amz-Cf-Id: Evfdhs-pxFojnzkQWuG-Ubp6B2TC5xbunhavG8ivXURdp2fw_noXjw==
在这种情况下,CloudFront强制浏览器再次下载整个文件,如您所见:
(a)它知道自4月15日以来该文件尚未被修改(参见Last-Modified标题),以及
(b)CloudFront确实有一个文件的缓存副本(请参阅X-Cache标头)
也许您想知道我的浏览器是否正在发送有效的If-Modified-Since标头.的确是.以下是请求标头:
GET /code/shared/defs.js HTTP/1.1 Host: d2fn6fv5a0cu3b.cloudfront.net User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.9; rv:28.0) Gecko/20100101 Firefox/28.0 Accept: */* Accept-Language: en-US,en;q=0.5 Accept-Encoding: gzip,deflate DNT: 1 Referer: http://d2fn6fv5a0cu3b.cloudfront.net/ Connection: keep-alive If-Modified-Since: Tue,15 Apr 2014 17:36:18 GMT If-None-Match: "0152435d158cf1:0" Cache-Control: max-age=0
这是一个奇怪的情况.如果我只是坐在我的浏览器前面并继续执行页面重新加载(Cmd-R),那么大约一半时间CloudFront将正确返回304,而另一半时间它将错误地返回200以及所有内容.在与页面交互之前等待五分钟到期主要产生200个并且仅产生几个304.这种奇怪的行为适用于HTML页面上引用的所有文件(.css,.js,.png等)以及包含HTML页面本身.我知道我的应用程序编码正确,因为如上所述,直接点击ELB而不通过CloudFront会产生预期的304结果.有任何想法吗?
解决方法
配置CloudFront以将cookie转发到您的源[…] If-Modified-Since和If-None-Match条件请求不受支持.
奇怪,但事实上情况更糟糕;并不是将cookie转发到您的原始服务器会禁用条件请求,而是有时会禁用它们 – 直到HTTP结果代码(304 vs 200)几乎是随机的.
重要的是要注意,即使你根本不使用cookie,你也会被这种奇怪的行为所困扰.将Forward Cookies下拉列表设置为“None”仍然是绝对必要的,如下图所示:
将设置切换为“无”可修复原始帖子中描述的错误行为.
此解决方案为您提供了另一个问题.您告诉CloudFront在将请求转发到您的来源之前完全删除所有Cookie.但您的原始服务器可能需要这些cookie.此外,如果您使用ELB(负载均衡器)作为源,那么ELB依赖于维护粘性会话的关键cookie将被完全删除.不好.
cookie剥离问题的解决方案将取决于您的网站的组织方式.在我的情况下,只有在将AJAX数据发布到myDomain.com/ajax/时才需要传输cookie(与会话相关或其他方式).由于所有依赖于cookie的URL属于ajax / *类别,因此必须创建该路径的新行为规则,并且在该规则中,仅限该规则,Forward Cookies下拉列表设置为“All”而不是“没有.”
就是这样.希望这有助于某人.