How to make Microsoft XmlHttpRequest honor cache control directive
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();
I found that using If-None-Match
header, specifing a value that does not match the ETag
of the last request will work.
Eg:
req.open("GET", url, false);
req.setRequestHeader("If-None-Match", "\"doesnt-match-anything\"");
req.send();
This might or might not require that the responses include an ETag
. (I only tried it with a service that includes an ETag
value in each response.)
Could you append a bogus parameter on the end of your URI that changes with each request?
http.open("GET", "http://www.bankofcanada.ca/stat/fx-xml.xml?requestID=42", False, "", "");
I use this for a keep-alive session and it works great.
The trick is to use the header "If-Modified-Since" with a value newer that the one cached by the browser.
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);
My quick and dirty workaround at a standard Windows client was
- Internet Options
- General
- Browsing history Settings
- Check for newer Versions of stored pages:
tickle "(x) Every time I visit the Webpage"
Now my Msxml2.XMLHTTP.x.0 Object don't use the Cache anymore ...