IE不尊重过期

时间:2014-07-03 14:03:27

标签: internet-explorer browser-cache cache-control expires-header if-modified-since

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

3 个答案:

答案 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验证:

  • HTTP请求包含标头Cache-Control
  • HTTP响应包含标头Last-Modified
  • 第二次,HTTP请求包含Cache-ControlIf-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-ModifiedHTTP/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”。 它应该工作。