如何使Microsoft XmlHttpRequest荣誉缓存控制指令 [英] How to make Microsoft XmlHttpRequest honor cache control directive

查看:75
本文介绍了如何使Microsoft XmlHttpRequest荣誉缓存控制指令的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用MSXML的要做的就是添加请求标头:

 缓存控制: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显示该文件实际上是从我的缓存中提供的。



那怎么了? 最大年龄是否没有按照我的想法做?



来自 RFC 2616-超文本传输​​协议,第14部分:标头字段定义


其他指令允许用户代理修改
的基本到期机制。
可以在
请求中指定以下指令:



最大年龄

表示客户端为
愿意接受其年龄
不大于指定时间
的响应(以秒为单位)。除非还包括最大失效
指令,否则客户端
不愿意接受失效的
响应。


正是我想要的。



缓存控制:max-age = 0 不是我想要的,还是MSXML的 XmlHttpRequest 对象有问题吗?



更新一个



这是MSXML XmlHttpRequest COM对象:




  • CLSID:{88d96a0a-f192-11d4-a65f- 0040963251e5}

  • ProgID:Msxml2.XMLHTTP.6.0



更新两次



客户端添加 max-age 指令以遵守所有缓存。从RFC:


Cache-Control常规标题字段
用于指定
的指令沿请求/响应
链的所有缓存
机制都必须遵守
。指令指定了行为
,旨在防止
的缓存对请求
或响应产生不利影响。这些指令
通常会覆盖默认的缓存
算法。高速缓存伪指令是
单向的,因为请求中存在
a伪指令并不意味着
意味着响应中给定的伪指令是


最大年龄段不适用于服务器;对于服务器没有意义。它适用于用户和服务器之间的所有缓存系统。



更新三



来自 W3C XmlHttpRequest


如果用户代理实现了HTTP缓存,则应该尊重
Cache-Control
设置的请求标头 setRequestHeader() (例如
缓存控制:无缓存绕过
缓存)。它绝不能发送缓存控制
Pragma 请求标头$ b除非最终用户
明确要求这种行为
(例如,通过重新加载页面),否则$ b会自动生成。


按照他们的示例,我尝试使用 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 code>(如果通过 setRequestHeader 设置)。微软的XmlHttpRequest似乎不符合该要求。

解决方案

不幸的是, XMLHttpRequest 对象是以这种方式设计的,因为它基于WinInet。另外,不建议从服务器端使用它。您应该使用 ServerXMLHttpRequest ,具有相同的功能,但取决于 WinHTTP 代替。有关更多信息,请参见常见问题解答 ServerXMLHttp 文档的描述指出:


HTTP客户端堆栈提供了更长的时间
正常运行时间。 WinInet功能对服务器应用程序不是
至关重要的功能,例如
,例如URL缓存,
代理服务器的自动发现,HTTP / 1.1分块,
脱机支持以及对
Gopher和FTP协议不包含在新的HTTP子集中。$ p

这意味着不是使用< a href = https://msdn.microsoft.com/zh-cn/library/ms759148(v=vs.85).aspx rel = noreferrer> 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();


i'm issuing a request using MSXML's XmlHttpRequest object:

IXMLHttpRequest http = new XmlHttpRequest();
http.open("GET", "http://www.bankofcanada.ca/stat/fx-xml.xml", False, "", "");
http.send();

And the send succeeds, and i get my xml data.

Except that XmlHttpRequest didn't actually hit the network (i can see there no actual http request issued). And Process Monitor shows the file is actually being served from my cache:

So i want to instruct the XmlHttpRequest user agent that any cached content older than 0 seconds is too old. The standards way to do this is to add a request header:

Cache-Control: max-age=0

to the send request:

http = new XmlHttpRequest();
http.open("GET", "http://www.bankofcanada.ca/stat/fx-xml.xml", False, "", "");
http.setRequestHeader("Cache-Control", "max-age=0");
http.send();

And the send succeeds, and i get my xml data.

Except that XmlHttpRequest didn't actually hit the network (i can see there no actual http request issued). And Process Monitor shows the file is actually being served from my cache.

So what is wrong? Is max-age not doing what i think it does?

From 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.

Which exactly what i want.

Is Cache-Control: max-age=0 not exactly what i want, or is MSXML's XmlHttpRequest object buggy?

Update One

This is the MSXML XmlHttpRequest COM object:

  • CLSID: {88d96a0a-f192-11d4-a65f-0040963251e5}
  • ProgID: Msxml2.XMLHTTP.6.0

Update Two

The max-age directive is added by the client for all cache's to adhere to. From 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 is not for the server; it makes no sense for a server. It is intended for all caching systems between the user and the server.

Update Three

From W3C XmlHttpRequest:

If the user agent implements a HTTP cache it should respect Cache-Control request headers set by the setRequestHeader() (e.g., Cache-Control: no-cache bypasses the cache). It must not send Cache-Control or Pragma request headers automatically unless the end user explicitly requests such behavior (e.g. by reloading the page).

Following their example, i tried using the no-cache directive:

http = new XmlHttpRequest();
http.open("GET", "http://www.bankofcanada.ca/stat/fx-xml.xml", False, "", "");
http.setRequestHeader("Cache-Control", "no-cache");
http.send();

And the XmlHttpRequest client still services requests completely from the cache, without querying the server at all.

The W3C says that if there is a cache, it must honor Cache-Control if it is set through setRequestHeader. Microsoft's XmlHttpRequest doesn't seem to honor that requirement.

解决方案

Unfortunately the XMLHttpRequest object was designed this way, because it is based on WinInet. Also, it is not recommend to be used from the server side. You should use ServerXMLHttpRequest, which has the same functionality, but depends on WinHTTP instead. See the FAQ for more information. A description from the ServerXMLHttp documentation states that:

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.

This means that rather than using 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();

you can use 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();

or 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();

这篇关于如何使Microsoft XmlHttpRequest荣誉缓存控制指令的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆