设置远期未来会在代码中过期 - ASP.NET

时间:2009-12-18 11:50:44

标签: c# asp.net iis optimization web-optimization

有没有办法可以用ASP.NET以编程方式在代码中设置Expires Header?具体来说,我需要将它设置在整个文件夹和所有子文件夹上,并且该文件夹仅包含静态文件(JavaScript,CSS,图像等)而不包含aspx文件,因此我不能只将一些代码添加到aspx代码中-behind page_load。

我通常可以直接在IIS中设置它。但服务器被客户端锁定(我只有FTP访问Web应用程序目录进行部署),并且让客户端在IIS上设置Expires Header将需要一个冰河时代(它是一个公共部门/政府网站)。 / p>

我根据雅虎的建议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));
        }
    }
}

虽然这看起来不起作用。我在代码上放置了一个断点,它可以正常运行。但是,当我在Firefox中分析原始HTTP标头信息时,未设置过期值。请注意我正在使用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中的内置Web服务器和IIS7中(在Intergrated Pipeline模式下)。一位工作同事提到在IIS6上设置通配符映射以使HttpModules处理静态文件,但是如果我可以访问IIS6,我可以直接设置Far-Future Expires标头而不用打扰这个HttpModule。哦,好吧!

3 个答案:

答案 0 :(得分:3)

如果您使用的是IIS 7,最简单的方法是编写一个在集成模式下运行静态文件的HttpModule,并从那里设置Expires和Cache-Control标头。

更新

你的HttpModule应该可以工作,虽然我通常也会打电话:

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

更新2:

使用IIS 6,您必须以编程方式修改配置数据库。这是可能的,虽然它需要提升权限。

唯一的另一种选择是用C ++编写ISAPI模块。

答案 1 :(得分:1)

尽管YSLOW提出了建议,但您也可以阅读Atwood先生的文章YSlow: Yahoo's Problems Are Not Your Problems

来自文章:

  

添加过期标题(重量:11)

     

这本身并不错,但如果你这可能会造成很大的问题   弄错了。例如,在Microsoft的IIS中,Expires标头是   默认情况下总是关闭,可能是因为这个原因。通过   在HTTP资源上设置Expires标头,您告诉客户端   从不检查该资源的新版本 - 至少直到   Expires标头上的截止日期。当我说从来没有,我的意思是    - 浏览器甚至不会要求新版本;它只是假设它   缓存版本很好,直到客户端清除缓存,或者   缓存达到到期日期。雅虎注意到他们改变了   这些资源在需要刷新时的文件名。

所以我猜其中一个要点是:假设你改变了a的内容 master css文件,但你也没有重命名css文件。如果你采取 雅虎推荐,您的最终用户将无法获得更新版本 您编辑的文件,直到标题的到期日期为止。你是 对这种情况感到满意吗?

答案 2 :(得分:0)

提高性能的好方法包括:gzip压缩响应(不是最简单的IIS6),缩小静态文件(css,js),将静态文件合并在一起(一个大的CSS,一个大js),使用精灵。我们的想法是减少HTTP请求的总数,然后减少响应的大小。