20

我遇到了一个问题,我对 HTML 文件中引用的一些 JavaScript 文件进行了更改,但浏览器看不到这些更改。它保留缓存在浏览器中的副本,即使 Web 服务器具有较新的版本。

直到我强制浏览器清除缓存,我才能看到更改。

这是网络服务器配置吗?我是否需要将我的 JavaScript 文件设置为从不缓存?我在Google Web Toolkit中看到了一些有趣的技术,它们实际上在每次进行更新时都会创建一个的JavaScript 文件名。我相信这是为了防止代理和浏览器保留旧版本的 JavaScript 文件具有相同的名称。

某处是否有最佳实践列表?

4

9 回答 9

28

我们将产品内部版本号附加到所有 Javascript(和 CSS 等)的末尾,如下所示:

<script src="MyScript.js?4.0.8243">

浏览器会忽略问号后的所有内容,但升级会导致一个新的 URL,这意味着缓存重新加载。

这还有一个额外的好处,即您可以设置表示“从不缓存!”的 HTTP 标头。

于 2008-09-10T15:49:34.250 回答
9

它保留缓存在浏览器中的副本,即使 Web 服务器具有较新的版本。

这可能是因为设置了 HTTP Expires / Cache-Control 标头。

http://developer.yahoo.com/performance/rules.html#expires

我在这里写了这个:

http://www.codinghorror.com/blog/archives/000932.html

这本身并不是一个坏建议,但如果你弄错了,它可能会导致巨大的问题。例如,在 Microsoft 的 IIS 中,Expires 标头在默认情况下始终处于关闭状态,可能正是出于这个原因。通过在 HTTP 资源上设置 Expires 标头,您是在告诉客户端永远不要检查该资源的新版本——至少在 Expires 标头的到期日期之前不要检查。当我说从不时,我是认真的——浏览器甚至不会要求新版本;它只是假设它的缓存版本很好,直到客户端清除缓存,或者缓存达到到期日期。雅虎指出,当他们需要刷新这些资源时,他们会更改这些资源的文件名。

您在这里真正节省的只是客户端 ping 服务器以获取新版本并在资源未更改的常见情况下获取 304 not modified 标头的成本。这不是太多开销.. 除非你是雅虎。当然,如果您有一组几乎从不更改的图像或脚本,请务必利用客户端缓存并打开 Cache-Control 标头。缓存对浏览器性能至关重要;每个 Web 开发人员都应该深入了解 HTTP 缓存的工作原理。但对于那些可以受益的特定文件夹或文件,只能以手术的、有限的方式使用它。对于其他任何事情,风险大于收益。这当然不是您希望将其作为整个网站的默认设置打开的东西。除非您喜欢在每次内容更改时更改文件名。

于 2008-09-10T16:08:14.597 回答
7

@杰森和达伦

IE6将带有查询字符串的任何内容视为不可缓存。您应该找到另一种将版本号获取到 url 中的方法,例如假目录:

<script src="/js/version/MyScript.js"/>

并在满足请求之前删除服务器端 js 之后的第一个目录级别。

编辑:对不起所有;它是 Squid,而不是 IE6,它不会使用查询字符串进行缓存。更多信息在这里

于 2008-09-10T15:56:45.793 回答
7

我写了一篇关于我们如何在这里克服这个问题的博客文章:

避免 ASP.NET 中的 JavaScript 和 CSS 样式表缓存问题

基本上,在开发过程中,您可以在 CSS 文件的文件名之后向查询字符串添加一个随机数。当您进行发布构建时,代码会改为使用您的程序集的修订号。这意味着在您的生产环境中,您的客户端可以缓存样式表,但是每当您发布站点的新版本时,他们将被迫重新加载文件。

于 2009-07-30T20:00:10.353 回答
0

我也只是重命名的方法。它永远不会失败,而且很容易做到。

于 2008-09-10T15:48:29.947 回答
0

您的网络服务器是否发送了正确的标头来告诉浏览器它有一个新版本?我之前也将日期添加到查询字符串中。即 myscripts.js?date=4/14/2008 12:45:03 (只有日期会被编码)

于 2008-09-10T15:51:28.317 回答
0

在每次发布时,我们只需在所有静态资产的根路径前添加一个单调递增的整数,这会强制客户端重新加载(我们之前在 IE6 中看到过查询字符串方法中断)。例如:

  • 第 1 版:http://www.foo.com/1/js/foo.js
  • 第 2 版:http://www.foo.com/2/js/foo.js

它需要在每个版本中重新调整链接,但我们已经构建了自动将链接更改为我们的部署工具的功能。

完成此操作后,您可以使用 Expires/Cache-Control 标头,让客户端“永远”缓存 JS 资源,因为路径随每个版本而变化,我认为这是 @JasonCohen 的意思。

于 2008-09-10T16:03:28.477 回答
0

即使您不打算使用 powershell 来自动部署,这里也有一些非常有用的技术。

于 2008-09-10T16:08:55.763 回答
0

值得一提的是,我看到deviantART网站,相当大的一个,将他们的 JS 文件作为 54504.js 提供服务。我刚刚检查并看到他们现在将它们用作 v6core.css?-5855446573 v6core_jc.js?4150339741 等。

如果查询字符串的问题来自服务器,我想你可以或多或少地控制它。

于 2008-11-22T09:47:51.383 回答