输出缓存动态生成CSS

时间:2012-06-13 12:23:46

标签: asp.net asp.net-mvc http-caching

在我的应用程序中,用户可以选择修改其网站的CSS。

这种情况不太可能经常改变,但是当它发生时,我们需要确保他们及其网站访问者立即看到结果。

我们会记录用户更新其CSS的日期和时间,因此一个简单的解决方案就是在网址上添加时间戳。

但是,我想知道是否可以以编程方式设置缓存标头以强制浏览器在CSS文件发生更改时重新请求它。

2 个答案:

答案 0 :(得分:4)

如果您在网址中包含哈希值,即

http://server.example.com/styles/css.css?hash 

当哈希值发生变化时会重新加载,因为浏览器会从新网址中获取它:

版本1:

<style type="text/css" link="styles/css.css?hash=v1" />

第2版:

<style type="text/css" link="styles/css.css?hash=v2" />

客户端缓存是一个客户端问题,让他们按照自己的意愿行事:新的URL意味着资源已经更改,因此需要重新加载。由于客户端实现的不同,保持与缓存控制头相同的URL可能会让您陷入痛苦的世界。

如果放置缓存控制标题(last-modified,expires,ETAG),则无法确定CSS在更改时是否会刷新:

  • 因为激进的浏览器(或代理)缓存可能会忽略这些。
  • 因为您可能会在5月1日提供V1,截止日期为6月1日,并在5月15日更新为V2,您的客户将需要等待15天才能获得新版本。

使用url哈希,最糟糕的情况是客户端不会将您的css放入缓存中,但用户体验不会改变,因为它们总是获得最新版本。

对于到期日期或上次修改日期,最糟糕的情况是客户端获得旧版本,这将改变用户体验:)

答案 1 :(得分:1)

感谢Mathieu的回复,我正在使用输出缓存和版本号的组合来处理缓存失效。

输出缓存配置文件:

我创建了以下扩展方法来附加时间戳:

    public static string AppendTimeStamp(this string src, DateTime lastModified)
    {
        if (string.IsNullOrEmpty(src))
            return src;

        return string.Format("{0}?v={1}", src, lastModified.ToString("yyyyMMddHHmmss"));
    }

用法:

<link rel="stylesheet" href="@Url.Content("~/assets/usercss").AppendTimeStamp(CustomizationSettings.LastModified)"/>

如果您不想缓存文件,只需将DateTime.UtcNow作为最后修改日期传递。