11

我正在为一个项目研究这个,我想知道其他人正在做什么来防止每个新版本都提供陈旧的 CSS 和 JavaScript 文件。我不想附加时间戳或类似的东西,这可能会阻止对每个请求进行缓存。

我正在使用 Spring 2.5 MVC 框架,并且我已经在使用 google api 来提供原型和脚本。我还在考虑使用 Amazon S3 和新的 Cloudfront 产品来最大限度地减少网络延迟。

4

7 回答 7

14

我在请求中添加了一个带有修订号的参数,例如:

<script type="text/javascript" src="/path/to/script.js?ver=456"></script>

'ver' 参数会在每次构建时自动更新(从构建更新的文件中读取)。这确保脚本仅针对当前修订进行缓存。

于 2008-12-10T16:12:39.990 回答
4

与@eran-galperin 一样,我在对 JS 文件的引用中使用了一个参数,但我包含了一个服务器生成的对文件“最后修改”日期的引用。@stein-g-strindhaug 建议使用这种方法。它看起来像这样:

<script type="text/javascript" src="/path/to/script.js?1347486578"></script>

服务器忽略静态文件的参数,客户端可能会缓存脚本,直到日期代码更改。如果(且仅当)您修改服务器上的 JS 文件,日期代码将自动更改。

例如,在 PHP 中,我创建此代码的脚本如下所示:

function cachePreventCode($filename) {
    if (!file_exists($filename))
        return "";
    $mtime = filemtime($filename);
    return $mtime;
}

因此,当您的 PHP 文件包含对 CSS 文件的引用时,它可能如下所示:

<link rel="stylesheet" type="text/css" href="main.css?<?= cachePreventCode("main.css") ?>" />

...这将创建...

<link rel="stylesheet" type="text/css" href="main.css?1347489244" />
于 2012-09-12T22:35:37.383 回答
2

关于缓存文件,我还没有通过使用查询字符串方法遇到与过时缓存文件相关的错误问题。

然而,关于性能,并回应Todd B提到的按文件名加速,请查看 Steve Souders 的工作以了解有关该主题的更多信息:

“Squid 是一种流行的代理,它不会使用查询字符串缓存资源。当代理缓存后面的多个用户请求同一个文件时,这会损害性能 - 而不是使用每个人都必须向源服务器发送请求的缓存版本。”

“代理管理员可以更改配置以支持使用查询字符串缓存资源,当缓存标头指示合适时。但默认配置是 Web 开发人员最常遇到的。”

http://www.stevesouders.com/blog/2008/08/23/revving-filenames-dont-use-querystring/

于 2008-12-10T20:03:50.460 回答
1

使用带有标头的conditional get请求If-Modified-Since

于 2008-12-10T15:58:12.360 回答
1

这实际上是一个非常困难的问题,您可以花一些时间来设计正确的解决方案。

我建议使用 url 中内置的时间戳和/或版本发布您的文件,而不是:

/media/js/my.js 你最终得到:

/media/js/v12/my.js 或类似的东西。

您可以使用任何工具自动执行版本控制/时间戳。

这具有在推出新版本时不会破坏站点的额外好处,并允许您进行真正的并行测试(与仅剥离版本并发回最新文件的重写规则不同)。

使用 JS 或 CSS 需要注意的一件事是,当您在其中包含依赖 url(背景图像等)时,您需要确保 JS/CSS 时间戳/版本在内部资源发生变化时发生变化(以及重写它们,但这可以通过非常简单的正则表达式和资源清单来实现)。

无论您做什么,请确保不要在最后扔一个 ?vblah,因为当您这样做时,您基本上会将缓存扔出窗口(这是不幸的,因为它是迄今为止处理此问题的最简单方法)

于 2008-12-10T16:12:18.710 回答
0

如果您将文件的“修改时间”作为时间戳获取,它将被缓存,直到文件被修改。只需使用辅助函数(或在其他框架中调用的任何函数)来添加从文件中获取时间戳的 script/css/image 标记。在类似unix的系统(大多数幸存者都是)上,您可以简单地touch文件强制修改时间在必要时进行更改。

Ruby on Rails 在生产模式下使用此策略(默认情况下我会离开),并在开发模式下使用普通时间戳(以确保没有缓存某些内容)。

于 2008-12-10T18:12:36.487 回答
0

如果你使用 MAVEN,你可以使用这个,在 pom.xml 上添加:

<properties>
   <maven.build.timestamp.format>yyyyMMddHHmm</maven.build.timestamp.format>
   <timestamp>${maven.build.timestamp}</timestamp>
</properties>

有了这个,你可以在你的视图中访问 ${timestamp}。像这个样本:

<script type="text/javascript" src="/js/myScript.js?t=${timestamp}"></script>
于 2015-08-14T18:44:24.783 回答