IE(7-10)似乎不尊重过期。我打开提琴手,正在检查。如果响应有一个etag,那么它会执行304,否则它会为未来1年到期的资源执行200。我也试过设置最后一次修改。它似乎不起作用。 在chrome中有一个expires标签..它甚至没有出去到服务器(对于304)它已经缓存了。 这是一些Fiddler标题
Req Headers
GET /geoip/city?country=US&state=ID HTTP/1.1
X-Requested-With: XMLHttpRequest
Accept: */*
Referer: http://localhost/register/BG/57ac5960-f0d5-11e3-90d1-af2b2634c624
Accept-Language: en-US
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko
Connection: Keep-Alive
Host: localhost
Cookie: connect.sid=s%3AntN3Tq9zXgrnlo5YOR1bsSa0lHE987Nv.aBbljhmG5tpfYcIXMgonxnhhWaWwd%2BTQ4jIKLnqL4us
Response Headers
HTTP/1.1 200 OK
X-Powered-By: Express
Vary: X-HTTP-Method-Override, Accept-Encoding
expires: Sun Jul 05 2015 23:15:21 GMT-0400 (Eastern Daylight Time)
Content-Type: application/json; charset=utf-8
Content-Encoding: gzip
Date: Mon, 07 Jul 2014 03:15:21 GMT
Connection: keep-alive
Transfer-Encoding: chunked
并使用E-tag
req Headers
GET /geoip/city?country=US&state=ID HTTP/1.1
X-Requested-With: XMLHttpRequest
Accept: */*
Referer: http://localhost/register/BG/57ac5960-f0d5-11e3-90d1-af2b2634c624
Accept-Language: en-US
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko
Host: localhost
If-None-Match: W/"101c-2996882950"
Connection: Keep-Alive
Cookie: connect.sid=s%3AntN3Tq9zXgrnlo5YOR1bsSa0lHE987Nv.aBbljhmG5tpfYcIXMgonxnhhWaWwd%2BTQ4jIKLnqL4us
Response header
HTTP/1.1 304 Not Modified
X-Powered-By: Express
Vary: X-HTTP-Method-Override
expires: Sun Jul 05 2015 23:18:47 GMT-0400 (Eastern Daylight Time)
ETag: W/"101c-2996882950"
Date: Mon, 07 Jul 2014 03:18:48 GMT
Connection: keep-alive
根据Ruud的建议......这是req / response
GET /geoip/city?country=US&state=MO HTTP/1.1
Cache-Control: public, max-age=31536000
Accept: */*
X-Requested-With: XMLHttpRequest
Referer: http://localhost/register/BG/57ac5960-f0d5-11e3-90d1-af2b2634c624
Accept-Language: en-US
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko
Connection: Keep-Alive
If-None-Match: W/"3bf9-3115988671"
Host: localhost
Cookie: connect.sid=s%3AZvwd9g7PAbQl7QHVx0ucpBMNnELll1R_.6KIvAtRWv9FK3zxxXVZfJBCpSv962zxLeTkvGd7mQq8
HTTP/1.1 304 Not Modified
X-Powered-By: Express
Vary: X-HTTP-Method-Override
expires: Mon Jul 06 2015 08:37:49 GMT-0400 (Eastern Daylight Time)
Cache-Control: public, max-age=31536000
last-modified: Sat Jul 07 2012 08:37:49 GMT-0400 (Eastern Daylight Time)
ETag: W/"3bf9-3115988671"
Date: Mon, 07 Jul 2014 12:37:49 GMT
Connection: keep-alive
答案 0 :(得分:1)
您的HTTP请求不包含If-Modified-Since
标头。这通常意味着页面尚未缓存。这可能是由于缺少Cache-Control
标题。如果没有该标头,Web浏览器可能会应用自己的默认缓存行为。在IE7 / 8/9/10的情况下,可能类似于:“您的URL有一个查询字符串,我们不要缓存它。”
请尝试将此标头添加到HTTP请求中:
Cache-Control: public, max-age=31536000
您的HTTP请求包含X-Requested-With: XMLHttpRequest
,因此我假设您使用XMLHttpRequest将HTTP请求发送到Web服务器。您可以像这样添加标题:
req.setRequestHeader("Cache-Control", "public, max-age=31536000");
除了上述内容之外,您可能还需要在HTTP响应中使用Last-Modified
标头;客户端可能需要此日期/时间在下一个HTTP请求时放入If-Modified-Since
标头。
使用Fiddler验证:
Cache-Control
Last-Modified
Cache-Control
和If-Modified-Since
当其他所有方法都失败时,您甚至可以考虑将自己的If-Modified-Since
标头推送到HTTP请求中。
上述标题的文档可在http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html
的第14.9,14.25和14.29节中找到答案 1 :(得分:0)
一个可能的解释是:
Expires: Sun Jul 05 2015 23:15:21 GMT-0400 (Eastern Daylight Time)
不是有效的RFC 1123日期。尝试将response-header字段更改为:
Expires: Sun, 05 Jul 2015 23:15:21 GMT
RFC 2616州:
HTTP / 1.1客户端和缓存必须处理其他无效日期格式,特别是包括值“0”,如同过去一样(即“已经过期”)。
从那里开始,网络浏览器的行为取决于是否有Last-Modified
和/或ETag
响应标头字段。
Last-Modified
/ ETag
:由于Expires
的日期无效,并且没有Cache-Control
可以依赖(您测试了Cache-Control
,但使用 Last-Modified
/ ETag
,而非没有),缓存可能会被禁用;客户端将发送请求,服务器将以200响应。Last-Modified
/ ETag
:可以启用缓存,但Expires
的日期无效,因此客户端必须发送请求以验证缓存是否过时。服务器以304响应以确认缓存是否正常。从你的故事中我收集到的这正是IE 7-10所做的。
另一方面,RFC 2616注明:
鼓励日期值的接收者在接受非HTTP应用程序可能发送的日期值时非常健壮,有时在通过代理/网关检索或发布消息到SMTP或NNTP时就是这种情况。
因此,某些浏览器可能比其他浏览器更自由,并尽最大努力解析您的日期(Chromium issue 153759似乎只是建议)。这可以解释为什么当IE没有时,Chrome会访问缓存。
注意:除Cache-Control: public, max-age=31536000
之外(或替代)Expires
,您可以考虑将cat h1.txt b1.txt | sudo nc -l 91
添加到响应标头中。另见:
修改强> 我用IE9做了一个非常简单的测试。在Linux机器上,我反复运行以下命令(使其充当单次Web服务器):
h1.txt
这是我unix2dos
;因为我在Linux机器上创建它所以我必须使用\r\n
来确保每一行都以Expires
终止。相关的响应标头字段为Last-Modified
和HTTP/1.1 200 OK
Content-Type: text/html;charset=utf-8
Date: Sat, 12 Jul 2014 20:07:43 GMT
Expires: Sun, 05 Jul 2015 23:15:21 GMT
Last-Modified: Sat, 12 Jul 2013 20:07:43 GMT
Server: WEBrick/1.3.1 (Ruby/1.9.2/2014-01-23)
Content-Length: 252
Connection: keep-alive
。
b1.txt
XMLHttpRequest
是一个HTML页面,其中有一段JavaScript调用<html>
<head>
<title>Test</title>
</head>
<body>
<button onclick="SendReq()">Send request</button>
<script>
function SendReq() {
var rq = new XMLHttpRequest();
rq.open('GET', 'http://192.168.1.103:91/', true);
rq.send();
}
</script>
</body>
</html>
,向同一页面发送HTTP请求(因为我懒得设置另一个页面)。
tcp.port == 91
我没有安装Fiddler;我使用Wireshark(过滤Last-Modified
)来监控流量。事实上,我可以随时点击我网页上的按钮,没有流量,直到我清除IE9的缓存。
这意味着IE9的缓存工作正常;问题必须在Web服务器上;更具体的,在响应头中。任何小错误都可能破坏缓存。您的原始Expires头字段(具有非GMT日期)就是一个很好的例子。
正如皮埃尔所指出的那样,确实将ETag
和/或{{1}}放在响应头中,否则IE很可能会进行到Web服务器的往返,即使页面存在于缓存。但我怀疑每个网络浏览器都是如此,而不仅仅是传统的IE浏览器。
答案 2 :(得分:0)
我认为你并不了解Expires的用途。它只是告诉浏览器:“将它保存在缓存中直到...”但它没有告诉:“并且不检查它是否未被修改”! 所以使用“Expires”,并使用“Last-modified”,同时使用正确的(有效的RFC 1123)日期值:“Sun,05 Jul 2015 23:15:21 GMT”。 它应该工作。