在Laravel中使用HTTP缓存,生成静态文件路径

Sta*_*lav 1 php http-caching browser-cache laravel

我打算在我的下一个项目中使用Laravel框架.到目前为止,我仍然陷入组织项目中静态内容的链接(图像,脚本等).例如,我有这个缓存选项(缓存所有静态文件,nginx):

location ~* \.(jpg|jpeg|gif|css|png|js|ico|html)$ {
    expires max;
}
Run Code Online (Sandbox Code Playgroud)

如何建立文件main.js的链接?如果文件被修改,如何告诉代理文件已过期?

在我目前的项目中,我有版本控制系统,它使用文件修改时间为文件生成唯一的前缀.所以链接就像http://site.com/22566223435/js/main.js下次当文件更改链接自动更改时.

Laravel实现此功能的最佳做法是什么?谢谢!

vFr*_*sop 5

我会这样做作为一个查询字符串,它很容易,足够准确,不需要任何复杂的层来实现.只需将文件的最后修改作为查询字符串放在其链接上.这将强制浏览器刷新文件.

<link rel="stylesheet" type="text/css" href="/css/style.min.css?v=<?= File::modified(path('public').'/css/style.min.css') ?>" />
Run Code Online (Sandbox Code Playgroud)

为了简化这一过程,您可以创建一个简单的类,该类生成指向文件的链接并缓存最后一次修改以提高性能.如果您使用LESS编译器,它也可以通过自定义函数实现.

现在,关于服务器缓存,如果您的应用程序让很多用户真正从中受益,那么您应该研究CDN,它还可以处理全球分发,并且可以使用该查询字符串系统.

编辑:

也可以在Apache上使用RewriteRules来解决这个问题(对nginx没有任何经验可以帮助解决这个问题).用于生成查询字符串的相同技术可用于生成URI的前缀(或后缀).

您可以尝试的另一件事是定义一个主要用于处理静态资产的子域assets.example.com.该域可以由没有Laravel堆栈的Web服务器完全处理.但这很大程度上取决于您的资产在整个项目中的开发,编译和使用方式.

我们的方法:

在我们公司,我们将CloudFront和S3用于数据库实体资产.每个实体都有自己的S3目录,每个资产都通过唯一的文件名进行版本化(由md5生成,避免重新上载的资产重复).就像是:

/posts/876/060b90d67ac0c5e24da6de6ae547e3b1.jpg
Run Code Online (Sandbox Code Playgroud)

我们还在CloudFront上定义了10个子域,因此浏览器不会达到同一域的6-8个并发请求的限制:

cdn0.example.com
cdn1.example.com
cdn2.example.com
... and so on
Run Code Online (Sandbox Code Playgroud)

我们数据库中的每个条目都使用通过计算选择的独占子域resource.id % 10,这非常快,并且始终为每个实体返回相同的子域(帮助客户端和CloudFront缓存).这是您提供服务图像的最佳选择.

UI图像存储在独占的子域中assets.example.com,到目前为止还没有版本化,因为我们不会更改设计,如果我们这样做,我们可能会将新资产放在像/v2//newthemename/文件夹之类的东西中.这种方法对回滚甚至用户选择的主题有很大帮助.

Apache和Laravel /public目录中提供了CSS和JS .这不是最快的方法,但由于我们现在专注于开发,因此自动编译LESS和Closure更为重要.当我们为最终用户推出时,我们可能会想到一个自动部署系统,它编译资产,在S3/CloudFront上发布时间戳前缀并缓存它们的最后时间戳以进行视图渲染.