Истекает заголовки при тестировании в Chrome

Очень запутался насчет заголовка "Expires" здесь! Иногда это работает, как ожидалось, а иногда нет.

Я использую следующий код, чтобы установить мои заголовки срока действия. Обратите внимание, что это делается с ASP.NET в настраиваемом атрибуте MVC - это не очень важно здесь - но объясняет, где 'filterContext' идет от.

HttpCachePolicyBase cache = filterContext.HttpContext.Response.Cache;
TimeSpan cacheDuration = TimeSpan.FromSeconds(Duration);

// my own custom header so we know what time it was
filterContext.HttpContext.Response.AddHeader("CurrentTime", DateTime.Now.ToString());

cache.SetCacheability(HttpCacheability.Public);
cache.SetExpires(DateTime.Now.Add(cacheDuration));
cache.SetMaxAge(cacheDuration);
cache.AppendCacheExtension("must-revalidate, proxy-revalidate");

Это иногда дает мне такие заголовки:

Cache-Control: public, must-revalidate, proxy-revalidate, max-age=413
Date: Wed, 18 Feb 2009 05:24:19 GMT
Expires: Wed, 18 Feb 2009 05:21:12 GMT
CurrentTime: 2/17/2009 9:21:12 PM

Иногда так:

Cache-Control: public, must-revalidate, proxy-revalidate, max-age=600
Date: Wed, 18 Feb 2009 05:27:55 GMT
Expires: Wed, 18 Feb 2009 05:27:55 GMT
CurrentTime: 2/17/2009 9:27:55 PM

Я запускаю все через Fiddler и наблюдаю, когда что-то запрашивается повторно и когда оно поступает из кеша браузера.

Теперь странно то, что в IE кэширование всегда работает как положено. Ссылка на мой метод действия ASP.NET MVC появляется в Fiddler, а затем, когда я снова нажимаю на эту же ссылку, она поступает из кэша.

Однако в Chrome это иногда будет, а иногда не будет приходить из кеша! Под кешем я не имею в виду дополнительный HTTP-запрос.

Например, такая ссылка:

 http://ipv4.fiddler:62669/gallery/mainimage/2

придет из кеша в IE, но вернется с 200 в хроме. Тогда иногда в Chrome это происходит из кеша. Я попытался очистить кеш браузера и повторил попытку - каждый раз один и тот же результат.

Chrome пытается сделать что-то "умное" и просто с треском проваливается - или мне нужен дополнительный заголовок?

Что мне интересно, так это то, что мой Expires Дата заголовка никогда не бывает в будущем. если я посмотрю на заголовки Google для их размещенного файла jQuery, я увижу, что заголовки выглядят следующим образом (срок действия истекает здесь в 2010 году - через год).

Cache-Control: public, max-age=31536000
Date: Wed, 18 Feb 2009 05:44:53 GMT
Expires: Thu, 18 Feb 2010 05:44:53 GMT

Не должно быть, Истекает на самом деле в будущем?

Согласно спецификации HTTP:

Если ответ включает в себя как заголовок Expires, так и директиву max-age, директива max-age переопределяет заголовок Expires, даже если заголовок Expires является более ограничительным. Это правило позволяет исходному серверу предоставлять для данного ответа более длительное время истечения для кэша HTTP/1.1 (или более поздней), чем для кэша HTTP/1.0. Это может быть полезно, если некоторые кэши HTTP/1.0 неправильно рассчитывают возраст или время истечения, возможно, из-за десинхронизированных часов.

Поэтому кажется, что Chrome должен соблюдать директиву max-age, даже если "Expires" совпадает с текущим временем, но, похоже, он этого не делает.

2 ответа

Я нашел следующее в исходном коде ASP.NET MVC:

 public virtual void RenderView(ViewContext viewContext) {
        // TODO: Remove this hack. Without it, the browser appears to always load cached output
        viewContext.HttpContext.Response.Cache.SetExpires(DateTime.Now);
        ViewUserControlContainerPage containerPage = new ViewUserControlContainerPage(this);
        // Tracing requires Page IDs to be unique.
        ID = Guid.NewGuid().ToString();

        RenderViewAndRestoreContentType(containerPage, viewContext);
    }

Так что это объясняет, почему мой Expires заголовок всегда является текущим временем. Однако я действительно не думаю, что это то, что запускает Chrome, потому что я создал простейшую страницу, как показано ниже, и Chrome все еще довольно счастливо возвращался на сервер и давал мне 200

public partial class test : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        TimeSpan cacheDuration = TimeSpan.FromSeconds(33);
       var cache = Response.Cache;

        cache.SetCacheability(HttpCacheability.Public);
        cache.SetExpires(DateTime.Now.Add(cacheDuration));
        cache.SetMaxAge(cacheDuration);
        cache.AppendCacheExtension("must-revalidate, proxy-revalidate");
    }
}

Я в значительной степени пришел к выводу, что это Chrome делает что-то действительно дурацкое с кэшированием.

Я упростил его до минимально возможного уровня - получения jQuery с сервера Google.

Я набрал:

http://ajax.googleapis.com/ajax/libs/jquery/1.3.1/jquery.min.js 

в Chrome, и Фиддлер выдал следующий 200 запрос:

Requests started at:    22:58:00:7756
Responses completed at: 22:58:03:5020
Total Sequence time:    00:00:02.7263880
DNS Lookup time:    531ms
TCP/IP Connect time:    63ms

RESPONSE CODES
--------------
HTTP/200:   1

Заголовки были следующими (обратите внимание, что срок действия истекает через 1 год после сегодняшнего дня):

Cache-Control: public, max-age=31536000
Date: Wed, 18 Feb 2009 06:58:01 GMT
Expires: Thu, 18 Feb 2010 06:58:01 GMT
Vary: Accept-Encoding

а затем я подождал несколько секунд и нажал Enter - на той же вкладке. Скрипач придумал ДРУГОЙ **200* запрос:

Requests started at:    22:58:09:2516
Responses completed at: 22:58:12:3999
Total Sequence time:    00:00:03.1482360

RESPONSE CODES
--------------
HTTP/200:   1

И заголовки были:

Cache-Control: public, max-age=31536000
Date: Wed, 18 Feb 2009 06:58:09 GMT
Expires: Thu, 18 Feb 2010 06:58:09 GMT
Vary: Accept-Encoding

Очевидно, это не то, что я ожидал.

Да - Accept-Encoding был одинаковым для обоих запросов.

Да - третий запрос дал мне 304

Это была новая версия Chrome, на которой я никогда не занимался разработкой, и на которой я только что впервые установил Fiddler.

Я не могу ждать, пока кто-нибудь объяснит мне это. Сейчас я сдаюсь - я думаю, что мой код кэширования и истечения срока действия в порядке. Кроме того, ASP.NET MVC, кажется, заставляет Expires быть текущим временем. Это, очевидно, не является фактором в моем примере Google.

Я думаю, что Chrome слишком умный, и это должно быть ошибкой - я нахожусь на версии 1.0.154.48.

Другие вопросы по тегам