Установка дальнего будущего истекает заголовок в коде - ASP.NET
Есть ли способ, которым я могу программно установить заголовок Expires в коде с ASP.NET? В частности, мне нужно установить его на всю папку и все подпапки, и папка содержит только статические файлы (JavaScript, CSS, изображения и т. Д.), А не файлы aspx, поэтому я не могу просто добавить некоторый код в код aspx За страницу загрузки.
Я обычно могу установить это непосредственно в IIS. Но сервер заблокирован клиентом (у меня есть только FTP-доступ к каталогу веб-приложений для развертываний), и получение клиентом установки заголовка Expires на IIS потребует ледникового периода (это сайт государственного сектора / правительства).
Я делаю это с целью оптимизации Front-End в соответствии с рекомендациями Yahoo http://developer.yahoo.com/performance/rules.html
Обновление: я пытался создать 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 ответа
Если вы используете IIS 7, самый простой способ сделать это - написать HttpModule для статических файлов в интегрированном режиме и установить оттуда заголовки Expires и Cache-Control.
Обновить:
Ваш HttpModule должен работать, хотя я обычно также звоню:
context.Response.Cache.SetMaxAge(TimeSpan.FromDays(365.));
Обновление 2:
В IIS 6 вам придется программно изменять метабазу. Это возможно, хотя требует повышенных разрешений.
Единственный вариант - написать модуль ISAPI на C++.
Несмотря на то, что YSLOW сделал рекомендацию, вы также можете извлечь пользу из прочтения статьи г-на Этвуда: YSlow: проблемы Yahoo - не ваши проблемы.
Из статьи:
Добавьте заголовок Expires (Вес: 11)
Это не плохой совет, как таковой, но он может вызвать огромные проблемы, если вы ошибетесь. Например, в Microsoft IIS заголовок Expires всегда отключен по умолчанию, возможно, именно по этой причине. Устанавливая заголовок Expires для ресурсов HTTP, вы говорите клиенту никогда не проверять наличие новых версий этого ресурса - по крайней мере, до истечения срока действия заголовка Expires. Когда я говорю "никогда", я имею в виду - браузер даже не будет запрашивать новую версию; он будет просто предполагать, что его кешированная версия хороша, пока клиент не очистит кеш, или кеш не истечет. Yahoo отмечает, что они изменяют имя файла этих ресурсов, когда они нуждаются в их обновлении.
Итак, я думаю, один из выводов: предположим, что вы меняете содержимое мастер-файла CSS, но вы также не переименовываете файл CSS. Если вы воспользуетесь рекомендацией Yahoo, ваш конечный пользователь не получит обновленную версию отредактированного вами файла до истечения срока действия заголовка. Вам комфортно с таким сценарием?
Хорошие способы повышения производительности включают в себя: сжатие gzip ответов (не самое простое с IIS6), минимизацию статических файлов (css, js), объединение статических файлов (один большой css, один большой js), используя спрайты. Идея состоит в том, чтобы уменьшить общее количество HTTP-запросов, а затем уменьшить размер ответов.