ASP.NET:如何强制重新加载Web静态文件

时间:2010-07-14 19:23:01

标签: http caching http-caching

在进行网页时,客户端/浏览器会决定是否更新文件,如图像或.css或.js,或者是否从缓存中获取该文件。

如果是.aspx页面,则由服务器决定。

当然,在IIS级别或使用一些HttpModule技术,我可以更改请求的标头,告诉客户端文件应缓存的时间和长度。

现在,我确实有一个网站,其中.aspx与相应的.js齐头并进。所以,也许我在.js中有一些jQuery代码可以访问.aspx中的一个元素。如果我从.aspx中删除该元素,我也会调整.js。如果用户进入我的页面,他将获得新的.aspx,但他仍然可以获得旧的.js,从而产生有趣的效果。

我的网站使用了大量脚本和大量图片。出于性能原因,我在IIS中配置了这些文件“永不”过期。

现在,文件有时会更改,我想确保用户获取更新文件。

一开始我通过重命名文件来帮助自己。所以,我有SkriptV1.js和SkriptV2.js等等。这是关于最糟糕的选择,因为存储库历史记录已被破坏,我需要调整引用和文件名。

现在,我在这里进行了改进,只使用Skript.js更改了引用?v = 1或Skript.js?v = 2。 这会强制客户端刷新文件。它工作正常,但我仍然需要调整参考。

现在,这里有一个进一步的改进:

<script type='text/javascript' src='../scripts/<%# GetScriptLastModified("MyScript.js") %>'></script>

因此,“GetScriptLastModified”将附加?v =参数,如下所示:

protected string GetScriptLastModified(string FileName)
{
    string File4Info = System.Threading.Thread.GetDomain().BaseDirectory + @"scripts\" + FileName;
    System.IO.FileInfo fileInfo = new System.IO.FileInfo(File4Info);
    return FileName + "?v=" + fileInfo.LastWriteTime.GetHashCode().ToString();
}

因此,呈现的.js-Link对客户端看起来像这样:

<script type='text/javascript' src='/scripts/GamesCharts.js?v=1377815076'></script>

每次上传新版本时链接都会更改,我可以确定用户在更改时立即获取新脚本或图片。

现在,有两个问题: a)有更优雅的方法来实现这一目标吗? b)如果不是:有人猜测服务器上的性能开销会有多大?一个页面上可以容易地显示50个版本化元素,因此对于一个.aspx,GetScriptLastModified将被调用50次。

期待讨论:)

1 个答案:

答案 0 :(得分:0)

这个问题有几个不同的答案。

首先,如果您的文件每隔一段时间只更改一次,请将Expires和Cache-Control标头设置为在一年内过期。只有真正永远过期的文件才会说它们永不过期。你现在看到的问题是“永不过期”。

此外,如果您在提供大量图片和JavaScript时遇到网站性能问题,则通常接受的解决方案是使用CDN(内容分发网络)。有许多不同的提供商,我相信您可以找到符合您预算的提供商。从长远来看,你也可以节省资金,因为CDN将从IIS卸载大量的I / O和CPU时间。令人惊讶的是,它可以带来多大的不同。

最后,确保用户获取最新文件的一种方法是在您的资产网址中实施某种版本控制方案,以便缓存破坏。有许多不同的方法可以做到这一点,但一种(非常天真)的方法是每次部署到您的站点时都会增加一个版本号。

E.g。您的所有资产网址都会显示为/static/123/img/dog_and_pony.jpg

然后,下次部署到您的站点时,您将增加版本号,使其为“124”。您需要一些方法来跟踪版本,动态地将其注入资产URL,以及确保每次部署时版本号都会更改。我们的想法是,引用此资产的任何内容都应自动知道新的版本号。

在性能方面,一个令人钦佩的目标是永远不需要用户刷新或必须两次下载相同的东西。但有时它只会减少麻烦,如果用户只是定期刷新所有内容,那对大多数网站来说都可能没问题。

希望这有帮助。