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

发布于 2024-09-10 01:58:26 字数 1518 浏览 4 评论 0原文

在处理网页时,客户端/浏览器决定是否更新图像、.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 次。

期待讨论:)

When doing webpages, the client/browser decides if it updates a file like an image or .css or .js or if it takes that from the Cache.

In case of .aspx page it is the server who decides.

Sure, on IIS level or also using some HttpModule techniques I can change the headers of requests to tell the client if and how long a file should be cached.

Now, I do have a website where the .aspx goes hand-in-hand with a corresponding .js. So, perhaps I have some jQuery code in the .js which accesses an element in the .aspx. If I remove that element from the .aspx I would also adapt the .js. If the user goes to my page he will get the new .aspx but he might still get the old .js, leading to funny effects.

My site uses lots of scripts and lots of images. For performance reasons I configured in the IIS that those files "never" expire.

Now, from time to time a file DOES change and I want to make sure that users get the update files.

In the beginning I helped myself by renaming the files. So, I had SkriptV1.js and SkriptV2.js and so on. That's about the worst option since the repository history is broken and I need to adapt both the references and the file name.

Now, I improved here and change only the references by using Skript.js?v=1 or Skript.js?v=2.
That forces the client to refresh the files. It works fine, but still I have to adapt the references.

Now, there is a further improvement here like this:

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

So, the "GetScriptLastModified" will append the ?v= parameter like this:

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();
}

So, the rendered .js-Link would look like this to the client:

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

The link will change every time, when I upload a new version and I can be sure that the user immediately gets a new script or image when I change it.

Now, two questions:
a) Is there a more elegant way to achieve this?
b) If not: Has someone a guess how big the performance overhead on the server would be? There can be easily 50 versioned elements on one page, so for one .aspx the GetScriptLastModified would be invoked 50 times.

Looking forward to a discussion :)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

清眉祭 2024-09-17 01:58:26

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

首先,如果您的文件只是偶尔更改一次,请将 Expires 和 Cache-Control 标头设置为在一年内过期。只有当文件确实永不过期时,您才可以说它们永不过期。您现在看到了“永不过期”的问题。

此外,如果您的网站因提供大量图像和 JavaScript 而遇到性能问题,普遍接受的解决方案是使用 CDN(内容交付网络)。有许多不同的提供商,我相信您一定能找到一个符合您预算的提供商。从长远来看,您还可以节省资金,因为 CDN 将从 IIS 卸载大量 I/O 和 CPU 时间。它能产生如此之大的变化,令人震惊。

最后,确保用户获得几乎永远不会更改的最新文件的一种方法是在资产 URL 中实施某种版本控制方案,以实现缓存清除。有许多不同的方法可以做到这一点,但一种(非常简单的)方法是每次部署到站点时版本号都会增加。

例如,您的所有资产 URL 将类似于 /static/123/img/dog_and_pony.jpg

然后,下次部署到您的站点时,您可以增加版本号,使其变为“124”。您需要某种方法来跟踪版本,将其动态注入到资产 URL 中,并确保每次部署时版本号都会发生变化。这个想法是,任何引用该资产的东西都应该自动知道新的版本号。

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

希望这有帮助。

There are a few different answers to this question.

First of all, if you have files which only change every once in a while, set the Expires and Cache-Control headers to expire in one year. Only if the files truly never expire should you say that they never expire. You're seeing the issues with saying "never expire" right now.

Also, if you are having performance issues on your site from serving up lots of images and JavaScript, the commonly accepted solution is to use a CDN (Content Delivery Network). There are many different providers and I'm sure that you can find one that meets your budget. You'll also save money in the long run as the CDN will offload a great deal of I/O and CPU time from IIS. It's astounding how big of a difference it can make.

Lastly, one way to make sure that users are getting the latest for your files which almost never change is to implement some sort of versioning scheme in your assets URLs to make cache busting happen. There are many different ways to do this, but one (very naive) way to do it is to have a version number that increases every time you deploy to your site.

E.g. all your asset URLs will look like /static/123/img/dog_and_pony.jpg

Then, next time you deploy to your site, you increase the version number so that it's "124". You would need some way to keep track of the version, dynamically injecting it into asset URLs, as well as making sure that the version number changes every time you deploy. The idea being that anything referencing this asset should automatically know the new version number.

In terms of performance, it's an admirable goal to never need the user to refresh or have to download the same thing twice. But sometimes it's just a lot less hassle, and if users are only refreshing everything periodically, that's probably okay for most websites.

Hope this helps.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文