我正在使用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是添加请求标头:
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:
其他指令允许用户代理 修改基本的到期机制。 可以在a上指定这些指令 请求:
最大年龄
表示客户端是 愿意接受年龄的回应 不大于指定的时间 很快。除非最大化 指令也包括在内,客户端 不愿意接受陈旧 响应。
这正是我想要的。
Cache-Control: max-age=0
不完全是我想要的,还是MSXML的XmlHttpRequest
对象错误?
这是MSXML XmlHttpRequest
COM对象:
客户端为所有要遵守的缓存添加max-age
指令。来自RFC:
Cache-Control通用标头字段 用于指定指令 必须遵守所有缓存 请求/响应中的机制 链即可。指令指定行为 旨在防止缓存 不利地干扰了请求 或回应。这些指令 通常会覆盖默认缓存 算法。缓存指令是 单向的,存在的 请求中的指令不会 意味着同样的指令是 在答复中给出。
Max-age不适用于服务器;它对服务器没有意义。它适用于 用户和服务器之间的所有缓存系统。
如果用户代理实现了HTTP缓存,应该尊重
Cache-Control
请求标头设置setRequestHeader()
(例如,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似乎并不尊重这一要求。
答案 0 :(得分:16)
不幸的是,XMLHttpRequest
对象是以这种方式设计的,因为它基于WinInet。此外,不建议从服务器端使用。您应该使用ServerXMLHttpRequest
,它具有相同的功能,但取决于WinHTTP
。有关详细信息,请参阅FAQ。 ServerXMLHttp
文档中的说明指出:
HTTP客户端堆栈提供更长时间 正常运行时间。 WinInet的功能不是 对服务器应用程序至关重要 作为URL缓存,自动发现 代理服务器,HTTP / 1.1分块, 离线支持和支持 Gopher和FTP协议不是 包含在新的HTTP子集中。
这意味着不是使用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();
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();
答案 1 :(得分:5)
我发现使用If-None-Match
标头时,指定的值与上一个请求的ETag
不匹配。
例如:
req.open("GET", url, false);
req.setRequestHeader("If-None-Match", "\"doesnt-match-anything\"");
req.send();
这可能会或可能不会要求回复包含ETag
。 (我只在每个响应中使用包含ETag
值的服务进行了尝试。)
答案 2 :(得分:1)
您是否可以在URI的末尾添加一个伪造参数,该参数随每个请求而变化?
http.open("GET", "http://www.bankofcanada.ca/stat/fx-xml.xml?requestID=42", False, "", "");
答案 3 :(得分:1)
我将它用于保持活动的会话,它很有效 诀窍是使用标题“If-Modified-Since”,其值比浏览器缓存的值更新。
g_AjaxObj.onreadystatechange = function() { if(g_AjaxObj.readyState === 4) { AjaxOnComplete_("KeepAlive"); }};
g_AjaxObj.open('GET', URL, true);
g_AjaxObj.setRequestHeader("If-Modified-Since", new Date().toUTCString());
g_AjaxObj.send(null);
答案 4 :(得分:1)
我在标准Windows客户端的快速而肮脏的解决方法是
- 互联网选项
- 总则
- 浏览历史记录设置
- 检查存储页面的较新版本:
发痒"(x)每次访问网页时都会出现#34;
现在我的 Msxml2.XMLHTTP.x.0 对象不再使用缓存......
答案 5 :(得分:1)
尝试将' cache-control:private' 作为标头发送。这对我有用:
var request = new XMLHttpRequest();
request.open("GET", 'http://myurl.com' , false);
request.setRequestHeader("cache-control", "private");
我正在撰写HTML&适用于Windows 8的Javascript应用程序,其中包括no-cache和max-age。对我来说,上面的工作正常。
我对标题并不熟悉,所以对缓存控制进行了一些挖掘:私有...
Indicates that all or part of the response message is intended for a single user and MUST NOT be cached by a shared cache, such as a proxy server.
来自What is Cache-Control: private? 和http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html
所以,基本上,这永远不会创建一个缓存条目,因此不会添加我们知道多余的缓存条目,就像使用“缓存 - 缓存”一样。随机数参数。
答案 6 :(得分:0)
这个标题是针对服务器的,并且由于浏览器没有事件做任何请求,它是无用的。
一个简单的技巧就是像这样加载页面:
http.open("GET", "http://www.bankofcanada.ca/stat/fx-xml.xml?"+Math.random(), False, "", "");
答案 7 :(得分:0)
答案 8 :(得分:0)
这样做的缺点是你用多份副本来充斥缓存 相同的内容。它可能是一个关于bug的http代理的黑客 - 但是a 真正的解决方案是使用缓存机制,而不是反对 他们。 -
我同意这不是理想的,也不是真正的解决方案,但是Mozilla实际上建议将其作为一种解决方法,所以我认为它一定不能太糟糕 - https://developer.mozilla.org/en-US/docs/DOM/XMLHttpRequest/Using_XMLHttpRequest
此外,我正在试图解决这个问题。我不得不依赖我的用户清理他们的浏览器(他们一直忘记这样做)。所以这对我来说是个天赐之物!
答案 9 :(得分:0)
这让我发疯了。这个SO线程最接近提供答案。不幸的是,在测试过程中,没有一个真的对我有用我发现测试工作正常的唯一解决方案是设置:
Header Pragma:no-cache
我希望通过IE头痛来拯救其他人。
BTW这是StackOverflow线程很好地阐明了Pragma和Cache-control之间的区别: Difference between Pragma and Cache-control headers?