我会把它作为一个查询字符串来做,它很简单,足够准确,不需要任何复杂的层来实现。只需将文件的最后修改作为查询字符串放在其链接上。这将强制浏览器刷新文件。
<link rel="stylesheet" type="text/css" href="/css/style.min.css?v=<?= File::modified(path('public').'/css/style.min.css') ?>" />
为了简化这一点,您可以创建一个简单的类来生成文件链接并缓存最后的修改以提高性能。如果您使用 LESS 编译器上的自定义函数,它也可以实现。
现在,关于服务器缓存,如果您的应用程序有很多用户可以真正从中受益,那么您应该研究 CDN,它还可以处理全球分布,并且可以与该查询字符串系统完美配合。
编辑:
也可以使用 Apache 上的 RewriteRules 来解决这个问题(没有任何使用 nginx 的经验来帮助解决这个问题)。用于生成查询字符串的相同技术,您可以用来生成 URI 的前缀(或后缀)。
您可以尝试的另一件事是定义一个主要用于处理静态资产的子域,例如assets.example.com
. 这个域可以完全由没有 Laravel 堆栈的网络服务器处理。但这在很大程度上取决于您的资产是如何在整个项目中开发、编译和使用的。
我们的方法:
在我们公司,我们将 CloudFront 和 S3 用于数据库实体资产。每个实体都有自己的 S3 目录,每个资产都通过唯一的文件名进行版本控制(由 md5 生成,这避免了重新上传资产的重复)。就像是:
/posts/876/060b90d67ac0c5e24da6de6ae547e3b1.jpg
我们还在 CloudFront 上定义了 10 个子域,因此浏览器不会达到同一域的 6-8 个并发请求的限制:
cdn0.example.com
cdn1.example.com
cdn2.example.com
... and so on
我们数据库中的每个条目都使用通过计算选择的专有子域resource.id % 10
,这非常快,并且总是为每个实体返回相同的子域(帮助客户端和 CloudFront 缓存)。这是提供图像的最佳选择。
UI 图像存储在一个专有的子域中assets.example.com
,并且到目前为止还没有版本化,因为我们不会对设计进行太多更改,如果我们这样做了,我们可能会将新资产放在一个/v2/
或/newthemename/
文件夹之类的东西中。这种方法对回滚甚至用户选择的主题有很大帮助。
CSS and JS are served by Apache from within Laravel /public
directory. This is not the fastest way, but since we are focused on development right now, having automatic compiling of LESS and Closure is far more important. When we launch for end users, we will probably think of an automated deploy system which compiles assets, publishes them on S3/CloudFront with a timestamp prefix and caches their last timestamp for view rendering.