我们有一个基于 Flash 的应用程序,它使用大量不同的 SWF 文件以及大量 HTML、Javascript、PHP、XML 和图像文件。服务器运行的是 NGINX 1.13.3。(我们正在开发 HTML5/JS 替代品,我认为这里的问题也适用于它。)
我们的webroot下的文件组织如下:
/client/client.php
/client/client_v48
app.php
MainLine.swf
other files and subdirectories
/client/current_client symlink to client_v48
目前的工作方式是这样的:
client.php
发送重定向到current_client/app.php?cb=<randomstring>
。app.php
返回应用程序主页的 HTML,其中包括<object>
加载 的标签MainLine.swf
,然后加载所需的所有其他资源。在整个应用程序中,所有内容都使用相对 URL,我们不会v48
在任何地方进行硬编码。
因此,现在我们要发布应用程序的 v49。我们创建一个/client/client_v49
目录,将所有文件部署到该目录,然后更改符号链接。但许多浏览器仍然缓存了旧版本的文件。重定向上的缓存破坏器确保它们获得最新版本的app.php
,但应用程序中使用的所有其他 URL 上都没有缓存破坏器。所有 URL 都是/client/current_client/...
,它们不会从一个版本更改为下一个版本。
我们如何确保在发布新版本时,客户端能够获取所有内容的最新版本。我们可以发送Cache-Control
标头,但这似乎还不够好。缓存中的不同文件可能会在不同时间过期,因此客户端最终可能会得到来自不同版本的混合文件。
过去,我们通过将客户端放入 iframe 中来解决这个问题。client.php
其中包含类似以下内容:
<iframe src="client_v48/app.php"><iframe>
当我们发布新版本时,我们会更改 iframe 源中的版本号。用户在浏览器位置看不到版本号,因此他们不会无意中将其添加到书签中。但我们的一些广告提供商不允许嵌入 iframe 中,因此我们不得不取消此功能。
那时我们切换到通过符号链接使用重定向current_client
,并遇到了缓存问题。
从那时起,我们一直在为符号链接赋予不同的名称current_client
。因此,当我们发布 v49 时,我们创建了一个新链接:
/client/curclient => client_v49
并将client.php
重定向更改为curclient/app.php
。这似乎很不干净,一定有更好的方法。此外,自上次更新以来已超过 4 个月,我们仍然看到上一个符号链接的点击次数很少,这表明一些用户已将其添加到书签中,因此即使这也不是一个完美的解决方案。
其他网站如何确保在部署新版本时所有缓存文件保持同步?我们是否只发送一个非常短的Max-Age
所有内容,以保持窗口非常小?
答案1
已经过去很长时间了,但这样的事情应该有效。
location ~ \.(swf)$ {
expires -1;
}