我正在使用MSXML的XmlHttpRequest对象发出请求:
IXMLHttpRequest http = new XmlHttpRequest();
http.open("GET", "http://www.bankofcanada.ca/stat/fx-xml.xml", False, "", "");
http.send();
当然send
方法成功执行,我也得到了XML数据。
但是XmlHttpRequest
实际上并没有发送网络请求(我可以看到没有实际的HTTP请求),而且进程监视器显示文件实际上是从我的缓存中提供的:
所以我想让XmlHttpRequest
用户代理知道任何缓存内容超过0秒就太旧了。按照标准方式,需要添加一个请求头来实现这一点:
Cache-Control: max-age=0
发送请求的代码:
http = new XmlHttpRequest();
http.open("GET", "http://www.bankofcanada.ca/stat/fx-xml.xml", False, "", "");
http.setRequestHeader("Cache-Control", "max-age=0");
http.send();
发送请求成功并获取了XML数据,但XmlHttpRequest
没有实际访问网络(我可以看到没有发出实际的HTTP请求)。而且"Process Monitor"显示文件实际上是从我的缓存中提供的。
那么问题出在哪里呢?是max-age
不做我想做的吗?
来自RFC 2616 - Hypertext Transfer Protocol,Part 14:Header Field Definitions:
其他指令允许用户代理修改基本过期机制。这些指令可以在请求中指定:
max-age
表示客户端愿意接受其年龄不超过指定时间(以秒为单位)的响应。除非还包括max-stale指令,否则客户端不愿意接受陈旧的响应。
这正是我想要的。
Cache-Control:max-age = 0
不完全是我想要的吗?还是MSXML的XmlHttpRequest
对象存在错误?
更新一
这是MSXML XmlHttpRequest
COM对象:
- CLSID:{88d96a0a-f192-11d4-a65f-0040963251e5}
- ProgID:Msxml2.XMLHTTP.6.0
更新二
max-age
指令由客户端为所有缓存添加以遵循。来自RFC:
Cache-Control通用头字段用于指定必须遵守请求/响应链上所有缓存机制的指令。这些指令指定旨在防止缓存与请求或响应产生不利干扰的行为。这些指令通常会覆盖默认的缓存算法。高速缓存指令是单向的,因为请求中存在指令并不意味着相同的指令也应该在响应中给出。
Max-age不适用于服务器;对于服务器而言是没有意义的。它是针对用户和服务器之间的所有缓存系统。
更新三
如果用户代理实现了HTTP缓存,则应尊重由
setRequestHeader()
设置的Cache-Control
请求标头(例如,Cache-Control:no-cache
跳过缓存)。它不应该自动发送Cache-Control
或Pragma
请求标头,除非最终用户明确请求这种行为(例如通过重新加载页面)。
遵循他们的示例,我尝试使用no-cache
指令:
http = new XmlHttpRequest();
http.open("GET", "http://www.bankofcanada.ca/stat/fx-xml.xml", False, "", "");
http.setRequestHeader("Cache-Control", "no-cache");
http.send();
XmlHttpRequest
客户端仍然完全从缓存中服务请求,而不会查询服务器。
根据W3C的规定,如果存在缓存,则必须遵守Cache-Control
(如果通过setRequestHeader
设置了该值)。然而,微软的XmlHttpRequest似乎不遵守这个要求。
ServerXmlHttpRequest
和WinHttpRequest
进行了测试。这两个都不会进行任何缓存。而XmlHttpRequest
确实执行缓存,但它不遵循 W3C 的规范来绕过该缓存的请求。+1 并接受。 - Ian Boyd