xmlhttprequest msxml cache-control

Cómo hacer que Microsoft XmlHttpRequest cumpla con la directiva de control de caché



msxml cache-control (10)

La desventaja de eso es que inunda el caché con varias copias del mismo contenido. Puede tratarse de piratear a los agentes http con errores, pero una solución real es trabajar con mecanismos de almacenamiento en caché, en lugar de contra ellos. -

Estoy de acuerdo en que esto no es ideal y no es realmente una solución, pero Mozilla realmente recomienda esto como una solución alternativa, por lo que creo que no debe ser demasiado terrible - https://developer.mozilla.org/en-US/docs/DOM/XMLHttpRequest/Using_XMLHttpRequest

Además, estaba arrancándome el pelo tratando de resolver esto. He tenido que confiar en que mis usuarios borren su navegador (algo que siempre olvidan hacer). Así que esto es una bendición para mí!

Estoy emitiendo una solicitud utilizando el objeto XmlHttpRequest de MSXML:

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

Y el send correctamente, y obtengo mis datos xml.

Excepto que XmlHttpRequest no llegó a la red (puedo ver que no se emitió ninguna solicitud de http real). Y Process Monitor muestra que el archivo está siendo servido desde mi caché:

Así que quiero indicar al agente de usuario XmlHttpRequest que cualquier contenido en caché que tenga más de 0 segundos es demasiado antiguo. La forma estándar de hacerlo es agregar un encabezado de solicitud:

Cache-Control: max-age=0

a la solicitud de envío:

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

Y el send correctamente, y obtengo mis datos xml.

Excepto que XmlHttpRequest no llegó a la red (puedo ver que no se emitió ninguna solicitud de http real). Y Process Monitor muestra que el archivo está siendo servido desde mi caché.

Entonces, ¿qué está mal? ¿ max-age no está haciendo lo que creo que hace?

De RFC 2616 - Protocolo de transferencia de hipertexto, Parte 14: Definiciones de campo de encabezado :

Otras directivas permiten que un agente de usuario modifique el mecanismo básico de caducidad. Estas directivas PUEDEN especificarse en una solicitud:

edad máxima
Indica que el cliente está dispuesto a aceptar una respuesta cuya edad no es mayor que el tiempo especificado en segundos. A menos que también se incluya la directiva máxima, el cliente no está dispuesto a aceptar una respuesta obsoleta.

Que es exactamente lo que quiero.

¿ Cache-Control: max-age=0 no es exactamente lo que quiero, o es el buggy del objeto XmlHttpRequest de MSXML?

Actualización uno

Este es el objeto COM MSXML XmlHttpRequest :

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

Actualización dos

El cliente agrega la directiva max-age para que todos los cachés se adhieran. Desde RFC:

El campo de encabezado general de Cache-Control se usa para especificar directivas que DEBEN ser obedecidas por todos los mecanismos de almacenamiento en caché a lo largo de la cadena de solicitud / respuesta . Las directivas especifican el comportamiento destinado a evitar que las memorias caché interfieran negativamente con la solicitud o respuesta. Estas directivas suelen anular los algoritmos de almacenamiento en caché predeterminados. Las directivas de caché son unidireccionales, ya que la presencia de una directiva en una solicitud no implica que la misma directiva deba darse en la respuesta.

La edad máxima no es para el servidor; no tiene sentido para un servidor. Está destinado a todos los sistemas de almacenamiento en caché entre el usuario y el servidor.

Actualización tres

Desde W3C XmlHttpRequest :

Si el agente de usuario implementa un caché HTTP, debe respetar los encabezados de solicitud de Cache-Control establecidos por setRequestHeader() (por ejemplo, Cache-Control: no-cache pasa por alto el caché). No debe enviar los encabezados de solicitud de Cache-Control o Pragma automáticamente a menos que el usuario final solicite explícitamente tal comportamiento (por ejemplo, recargando la página).

Siguiendo su ejemplo , intenté usar la directiva 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();

Y el cliente XmlHttpRequest aún XmlHttpRequest las solicitudes completamente desde la memoria caché, sin consultar el servidor en absoluto.

El W3C dice que si hay un caché, debe respetar Cache-Control si se establece a través de setRequestHeader . XmlHttpRequest de Microsoft no parece cumplir con ese requisito.


¿Podría agregar un parámetro falso al final de su URI que cambia con cada solicitud?

http.open("GET", "http://www.bankofcanada.ca/stat/fx-xml.xml?requestID=42", False, "", "");


Desafortunadamente, el objeto XMLHttpRequest fue diseñado de esta manera, porque está basado en WinInet. Además, no se recomienda su uso desde el lado del servidor. Debe usar ServerXMLHttpRequest , que tiene la misma funcionalidad, pero depende de WinHTTP lugar. Consulte las FAQ para obtener más información. Una descripción de la documentación de ServerXMLHttp indica que:

La pila de clientes HTTP ofrece tiempos de actividad más largos. Las funciones de WinInet que no son críticas para las aplicaciones de servidor, como el almacenamiento en caché de URL, el descubrimiento automático de servidores proxy, la fragmentación de HTTP / 1.1, la compatibilidad sin conexión y la compatibilidad con los protocolos Gopher y FTP no se incluyen en el nuevo subconjunto de HTTP.

Esto significa que en lugar de usar 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();

puedes usar 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();

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


Descubrí que usar el encabezado If-None-Match , especificando un valor que no coincida con la ETag de la última solicitud, funcionará.

P.ej:

req.open("GET", url, false); req.setRequestHeader("If-None-Match", "/"doesnt-match-anything/""); req.send();

Esto podría o no requerir que las respuestas incluyan un ETag . (Solo lo probé con un servicio que incluye un valor de ETag en cada respuesta).


Este encabezado es para el servidor, y como el navegador no hace ningún evento, no sirve de nada.

Un truco fácil es cargar la página de esta manera:

http.open("GET", "http://www.bankofcanada.ca/stat/fx-xml.xml?"+Math.random(), False, "", "");


Esto me estaba volviendo loco. Este hilo de SO se acercó más a proporcionar una respuesta. Desafortunadamente, durante la prueba ninguno de ellos realmente funcionó para mí. La única solución que encontré que probé para funcionar correctamente fue la configuración:

Encabezado Pragma: no-caché

Espero que salve a otros con dolores de cabeza en IE.

Por cierto, este hilo de es excelente para aclarar la diferencia entre Pragma y Cache-control: ¿ Diferencia entre Pragma y Cache-control headers?


Intenta enviar ''cache-control: private'' como encabezado. Esto funcionó para mí:

var request = new XMLHttpRequest(); request.open("GET", ''http://myurl.com'' , false); request.setRequestHeader("cache-control", "private");

Estoy escribiendo una aplicación HTML y Javascript para Windows 8 donde se ignoran y no-cache y max-age. Para mí lo anterior funciona bien.

No estaba familiarizado con el encabezado, así que hice un poco de investigación sobre el control de caché: privado ...

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.

¿ De qué es Cache-Control: privado? y http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html

Así que, básicamente, esto nunca creará una entrada de caché y, por lo tanto, no agrega entradas de caché que sabemos son superfluas, como con un parámetro de número aleatorio de ''caché-destructor''.


Mi solución rápida y sucia en un cliente estándar de Windows era
- Opciones de internet
- general
- Configuración del historial de navegación
- Compruebe si hay nuevas versiones de las páginas almacenadas:
tickle "(x) Cada vez que visito la página web"
Ahora mi objeto Msxml2.XMLHTTP.x.0 ya no usa el caché ...



Uso esto para una sesión de keep-alive y funciona muy bien.
El truco es usar el encabezado "If-Modified-Since" con un valor más nuevo que el almacenado en caché por el navegador.

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