Истекает заголовки при тестировании в Chrome - PullRequest
5 голосов
/ 18 февраля 2009

Очень запутался насчет заголовка «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 :

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

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

Ответы [ 2 ]

3 голосов
/ 18 февраля 2009

В исходном коде 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");
    }
}
1 голос
/ 18 февраля 2009

Я в значительной степени пришел к выводу, что 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.

...