我正在使用MSXML的XmlHttpRequest对象发出请求:
IXMLHttpRequest http = new XmlHttpRequest();
http.open("GET", "http://www.bankofcanada.ca/stat/fx-xml.xml", False, "", "");
http.send();
并且
send
成功,并且我得到了xml数据。
除了
XmlHttpRequest
并未真正到达网络之外(我可以看到没有发出实际的http请求)。而且Process Monitor显示文件实际上是从我的缓存中提供的:
因此,我想指示
XmlHttpRequest
用户代理,任何早于0秒的缓存内容都太旧了。
standards way为此添加一个请求 header :
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();
并且
send
成功,并且我得到了xml数据。
除了
XmlHttpRequest
并未真正到达网络之外(我可以看到没有发出实际的http请求)。而且Process Monitor显示文件实际上是从我的缓存中提供的。
那怎么了?
max-age
是否没有按照我的想法去做?
从 RFC 2616 - Hypertext Transfer Protocol, Part 14: Header Field Definitions:
Other directives allow a user agent to modify the basic expiration mechanism. These directives MAY be specified on a request:
max-age
Indicates that the client is willing to accept a response whose age is no greater than the specified time in seconds. Unless max- stale directive is also included, the client is not willing to accept a stale response.
正是我想要的。
Cache-Control: max-age=0
是否不完全是我想要的,还是MSXML的
XmlHttpRequest
对象 buggy ?
更新一
这是MSXML
XmlHttpRequest
COM对象:
更新二
客户端添加了
max-age
伪指令,以遵守所有缓存。从RFC:
The Cache-Control general-header field is used to specify directives that MUST be obeyed by all caching mechanisms along the request/response chain. The directives specify behavior intended to prevent caches from adversely interfering with the request or response. These directives typically override the default caching algorithms. Cache directives are unidirectional in that the presence of a directive in a request does not imply that the same directive is to be given in the response.
Max-age不适用于服务器;对于服务器没有意义。它适用于用户和服务器之间之间的所有缓存系统 。
更新三
从W3C XmlHttpRequest:
If the user agent implements a HTTP cache it should respect
Cache-Control
request headers set by thesetRequestHeader()
(e.g.,Cache-Control: no-cache
bypasses the cache). It must not sendCache-Control
orPragma
request headers automatically unless the end user explicitly requests such behavior (e.g. by reloading the page).
按照他们的示例,我尝试使用
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似乎不符合这一要求。
请您参考如下方法:
不幸的是,XMLHttpRequest
对象是按这种方式设计的,因为它基于WinInet。另外,不建议从服务器端使用它。您应该使用 ServerXMLHttpRequest
,它具有相同的功能,但取决于 WinHTTP
。有关更多信息,请参见FAQ。 ServerXMLHttp
文档的描述指出:
The HTTP client stack offers longer uptimes. WinInet features that are not critical for server applications, such as URL caching, auto-discovery of proxy servers, HTTP/1.1 chunking, offline support, and support for Gopher and FTP protocols are not included in the new HTTP subset.
这意味着,而不是使用 XmlHttpRequest:
IXMLHTTPRequest http = CreateComObject("Msxml2.XMLHTTP.6.0"); http.open("GET", "http://www.bankofcanada.ca/stat/fx-xml.xml", False, "", "");
http.setRequestHeader("Cache-Control", "max-age=0");
http.send();
您可以使用 ServerXmlHttpRequest:
IXMLHTTPRequest http = CreateComObject("Msxml2.ServerXMLHTTP");
http.open("GET", "http://www.bankofcanada.ca/stat/fx-xml.xml", False, "", "");
http.setRequestHeader("Cache-Control", "max-age=0");
http.send();
或 WinHttpRequest:
IWinHttpRequest http = CreateComObject("WinHttp.WinHttpRequest.5.1");
http.open("GET", "http://www.bankofcanada.ca/stat/fx-xml.xml", False, "", "");
http.setRequestHeader("Cache-Control", "max-age=0");
http.send();