tengo un método de acción que yo quiero para almacenar en caché:OutputCache está enviando mal cabecera Vary cuando la llamada se acierta en la caché
[OutputCache(Duration=60*5, Location=OutputCacheLocation.Any, VaryByCustom="index")]
public ActionResult Index()
{
return View();
}
Con este enfoque:
public override string GetVaryByCustomString(HttpContext context, string custom)
{
context.Response.Cache.SetOmitVaryStar(true);
context.Response.Cache.VaryByHeaders["Cookie"] = true;
if (User.Identity.IsAuthenticated)
{
Debug.Print("Authenticated");
context.Response.Cache.SetNoServerCaching();
context.Response.Cache.SetCacheability(HttpCacheability.Private);
return null;
}
else
{
Debug.Print("Non authenticated");
return custom;
}
}
La idea era keep a cached version of the page for non-authenticated users, but avoid caching for authenticated ones.
Pensé que siempre devolverá un Vary:Cookie
encabezado HTTP, pero no lo es. Hacer una prueba con Fiddler y la emisión de dos veces la misma petición, en la primera HTTP llaman va bien:
HTTP/1.1 200 OK
Cache-Control: public, max-age=300
Content-Type: text/html; charset=utf-8
Expires: Thu, 09 Feb 2012 10:53:36 GMT
Last-Modified: Thu, 09 Feb 2012 10:48:36 GMT
Vary: Cookie
Server: Microsoft-IIS/7.5
X-AspNetMvc-Version: 3.0
X-AspNet-Version: 4.0.30319
X-Powered-By: ASP.NET
Date: Thu, 09 Feb 2012 10:48:37 GMT
Content-Length: 441
Sin embargo, en la segunda, se sobrescribe la cabecera:
HTTP/1.1 200 OK
Cache-Control: public, max-age=297
Content-Type: text/html; charset=utf-8
Expires: Thu, 09 Feb 2012 10:53:36 GMT
Last-Modified: Thu, 09 Feb 2012 10:48:36 GMT
Vary: *
Server: Microsoft-IIS/7.5
X-AspNetMvc-Version: 3.0
X-AspNet-Version: 4.0.30319
X-Powered-By: ASP.NET
Date: Thu, 09 Feb 2012 10:48:39 GMT
Content-Length: 441
Así que, como Hasta donde yo sé, los navegadores no almacenan en caché la solicitud, incluso si es pública, ya que Vary:*
significa que la solicitud se ha generado con parámetros que no están en la URL ni en los encabezados HTTP. ¿Hay alguna manera de arreglar esto?
Atentamente.
ACTUALIZACIÓN:
De manera similar, cuando envío dos solicitudes autenticadas idénticos, la primera llamada se modificador private
, pero no la cabecera Vary
:
HTTP/1.1 200 OK
Cache-Control: private, max-age=300
Content-Type: text/html; charset=utf-8
Expires: Thu, 09 Feb 2012 12:43:14 GMT
Last-Modified: Thu, 09 Feb 2012 12:38:14 GMT
Server: Microsoft-IIS/7.5
X-AspNetMvc-Version: 3.0
X-AspNet-Version: 4.0.30319
X-Powered-By: ASP.NET
Date: Thu, 09 Feb 2012 12:38:14 GMT
Content-Length: 443
Pero la segunda obtiene la misma respuesta que una solicitud no autenticada:
HTTP/1.1 200 OK
Cache-Control: public, max-age=298
Content-Type: text/html; charset=utf-8
Expires: Thu, 09 Feb 2012 12:44:32 GMT
Last-Modified: Thu, 09 Feb 2012 12:39:32 GMT
Vary: *
Server: Microsoft-IIS/7.5
X-AspNetMvc-Version: 3.0
X-AspNet-Version: 4.0.30319
X-Powered-By: ASP.NET
Date: Thu, 09 Feb 2012 12:39:33 GMT
Content-Length: 443
He subido un test project showing the issue, por lo tanto, puede intentarlo.
Tenga en cuenta que existe un pedido IHttpModule
que establece una solicitud autenticada o no dependiendo de si la solicitud tiene una cookie o no, este no es un enfoque de "vida real", es solo para fines de prueba.
El proyecto contiene sólo una página web con un enlace a sí mismo, un enlace que conecta, y otro enlace que cierra la sesión:
- entrada: envía una galleta en una redirección
HTTP 302
para el hogar página otra vez - LogOut: envía de nuevo una cookie caducada en una reccion
HTTP 302
a la página de inicio.
El espera/ideales comportamiento sería: acceso
- usuario Índice, y obtener la página del servidor. La página muestra la fecha "A".
- Índice de acceso de usuario nuevamente y el navegador muestra la versión en caché. La página muestra la fecha "A".
- Limpiar el caché del navegador.
- Índice de acceso de usuario nuevamente y el navegador muestra la versión en caché del servidor. La página muestra la fecha "A".
- El usuario hace clic en iniciar sesión, y el operador obtiene una nueva página, que muestra la fecha "B".
- El usuario hace clic en cerrar sesión y el navegador obtiene la página del servidor en caché. La página muestra la fecha "A" nuevamente.
Pero este es el comportamiento hasta el momento:
- el acceso del usuario Índice, y recibe la página del servidor. La página muestra la fecha "A".
- Índice de acceso de usuario nuevamente y el navegador muestra la versión en caché. La página muestra la fecha "A".
- Limpiar el caché del navegador.
- Índice de acceso de usuario nuevamente y el navegador muestra la versión en caché del servidor. La página muestra la fecha "A".
- El usuario hace clic en iniciar sesión, y el operador obtiene una nueva página, que muestra la fecha "B".
- El usuario hace clic en cerrar sesión, y el navegador debe obtener la página del servidor en caché, pero no. La página muestra la fecha "B" nuevamente desde el caché del navegador. Esto se debe a la falta del encabezado
Vary
en la respuesta autenticada.
No sé si me pasa algo de malo en el almacenamiento en caché, me falta algo de detalle o el OutputCache
no funciona muy bien, pero agradecería cualquier orientación.
Saludos.
ACTUALIZACIÓN 2:
Mi intención es utilizar la semántica de caché HTTP para:
- Permitir a los navegadores y proxys caché de la versión "pública" de la página.
- Permitir que los navegadores guarden en caché la versión "autentificada" de la página para su usuario.
Si cambio de la declaración OutputCache para hacer el almacenamiento en caché sólo en el servidor y evitar que la corriente abajo y el cliente almacenamiento en caché:
[OutputCache(Duration=60*5, Location=OutputCacheLocation.Server, VaryByCustom="index")]
se comporta como se esperaba, pero se impide que la corriente abajo y el cliente de caché, y eso no es lo que quiero
¿Qué ocurre si también configura las otras propiedades de VaryBy en el atributo OutputCache del método? – bzlm
He agregado VaryByHeader = "Cookie", y todavía sucede, la segunda llamada obtiene un Vary = *. – vtortola
¿Qué pasa si prueba [el enfoque vinculado a en la pregunta vinculada] (http://visitmix.com/writings/using-varybycustom-with-outputcache-in-asp-net-mvc-to-support-caching-for- usuarios registrados) tal como están, sin variar por cookie o modificando los encabezados de respuesta dentro del método 'GetVaryByCustom' (Técnicamente, no es necesario que varíe por cookie para lograr el almacenamiento en caché solo para usuarios anónimos). – bzlm