Установка дальнего будущего истекает заголовок в коде - ASP.NET - PullRequest
6 голосов
/ 18 декабря 2009

Есть ли способ, которым я могу программно установить заголовок Expires в коде с ASP.NET? В частности, мне нужно установить его на всю папку и все подпапки, и папка содержит только статические файлы (JavaScript, CSS, изображения и т. Д.), А не файлы aspx, поэтому я не могу просто добавить некоторый код в код aspx - за загрузкой страницы.

Обычно я могу установить это непосредственно в IIS. Но сервер заблокирован клиентом (у меня есть только FTP-доступ к каталогу веб-приложения для развертываний), и получение клиентом установки заголовка Expires на IIS потребует ледникового периода (это сайт государственного сектора / правительства).

Я делаю это по соображениям Front-End в соответствии с рекомендациями Yahoo http://developer.yahoo.com/performance/rules.html#expires

Обновление: Я пытался создать HttpModule ...

public class FarFutureExpiresModule : IHttpModule
{
    public void Dispose() { }

    public void Init(HttpApplication context)
    {
        context.BeginRequest += new EventHandler(context_BeginRequest);
    }

    void context_BeginRequest(object sender, EventArgs e)
    {
        HttpContext context = HttpContext.Current;

        string url = context.Request.Url.ToString();

        if (url.Contains("/StaticContent/"))
        {
            context.Response.Cache.SetExpires(DateTime.Now.AddYears(30));
        }
    }
}

Хотя это не сработает. Я поместил точку останова на код, и он работает правильно. Однако, когда я анализирую необработанную информацию HTTP-заголовка в Firefox, значение expires не устанавливается. Обратите внимание, что я использую BeginRequest, но я также пытался подключиться к PostReleaseRequestState и PreSendRequestHeaders, и они, похоже, тоже не работают. Есть идеи?

Обновление 2: Хорошо, похоже, потому что я использую IIS6, HttpModules не будут работать для статических файлов, только для динамических файлов (* .aspx и т. Д.). Благодаря помощи RickNZ я разработал следующий модуль IHttpModule:

public class FarFutureExpiresModule : IHttpModule
{
    public void Dispose() { }

    public void Init(HttpApplication context)
    {
        context.BeginRequest += new EventHandler(context_BeginRequest);
    }

    void context_BeginRequest(object sender, EventArgs e)
    {
        HttpContext context = HttpContext.Current;

        string url = context.Request.Url.ToString();

        if (url.Contains("/StaticContent/"))
        {
            context.Response.Cache.SetExpires(DateTime.Now.AddYears(30));
            context.Response.Cache.SetMaxAge(TimeSpan.FromDays(365.0 * 3.0));
        }
    }
}

... и, похоже, работает, но только на встроенном веб-сервере в Visual Studio и в IIS7 (в режиме Intergrated Pipeline). Коллега по работе упомянул настройку сопоставления подстановочных знаков на IIS6, чтобы заставить HttpModules работать со статическими файлами, но если у меня есть доступ к IIS6, я мог бы просто установить заголовок Far-Future Expires напрямую и не беспокоиться об этом HttpModule. О, хорошо!

Ответы [ 3 ]

3 голосов
/ 18 декабря 2009

Если вы используете IIS 7, самый простой способ сделать это - написать HttpModule для статических файлов в интегрированном режиме и установить оттуда заголовки Expires и Cache-Control.

Обновление:

Ваш HttpModule должен работать, хотя я обычно также звоню:

context.Response.Cache.SetMaxAge(TimeSpan.FromDays(365.));

Обновление 2:

В IIS 6 вам придется программно изменять метабазу. Это возможно, хотя требует повышенных разрешений.

Единственный другой вариант - написать модуль ISAPI на C ++.

1 голос
/ 01 августа 2011

Несмотря на то, что YSLOW сделал рекомендацию, вы также можете извлечь пользу из прочтения статьи мистера Этвуда: YSlow: проблемы Yahoo - это не ваши проблемы .

Из статьи:

Добавление заголовка Expires (Вес: 11)

По сути, это неплохой совет, но если вы понять неправильно. Например, в Microsoft IIS заголовок Expires всегда выключен по умолчанию, вероятно, именно по этой причине. От устанавливая заголовок Expires на ресурсах HTTP, вы говорите клиенту никогда не проверять новые версии этого ресурса - по крайней мере, до дата истечения срока действия в заголовке Expires. Когда я говорю никогда, я имею в виду - браузер даже не будет запрашивать новую версию; он просто примет его Кэшированная версия хороша, пока клиент не очистит кеш или кеш достигает срока годности. Yahoo отмечает, что они меняют имя файла этих ресурсов, когда они нуждаются в обновлении.

Итак, я думаю, один из выводов: предположим, вы изменили содержимое главный файл CSS, но вы также не переименовываете файл CSS. Если вы берете Рекомендация Yahoo, ваш конечный пользователь не получит обновленную версию файл, который вы редактировали до истечения срока годности заголовка. Ты комфортно с таким сценарием?

0 голосов
/ 18 декабря 2009

Хорошие способы повышения производительности включают: сжатие gzip-ответов (не самое простое с IIS6), минимизацию статических файлов (css, js), объединение статических файлов (один большой css, один большой js), использование спрайтов. Идея состоит в том, чтобы уменьшить общее количество HTTP-запросов, а затем уменьшить размер ответов.

...