项目

常规

个人资料

操作

浏览器缓存

一般背景:为什么在浏览器中缓存是一个好事

在任何网站上,让浏览器缓存静态对象(即不包含用户内容,并且几小时、几天或几周都相同)都是一种好做法。

这通常意味着像.css、.js和图像文件这样的文件。

但某些内容变化非常快,所以不能被浏览器缓存。

如果浏览器被告知“不要缓存此对象”
那么它会知道不要。这就是网站(和Redmine)在可能更改的页面上所做的:例如,问题页面:它将在HTTP头中放入该消息。

但是,如果没有这样的说明 - 如果浏览器不确定它最近已经下载过的页面组件
它将向服务器发送一个304请求:表示“你能告诉我,这个文件是否仍然没有过时”。带有304的,服务器不需要再次发送整个对象:只需发送一个简短的“是的,它仍然新鲜”的回答。

在Redmine的默认设置中:它在每个页面上都会生成大量的304连接:您可以在Firebug等工具中看到这些。每个.css和.js文件等都有很多。

这对用户体验很不好:因为浏览器必须等待这些响应,然后才能继续构建页面。

因此,我们需要告诉浏览器这些对象不会长时间过时

有简单的方法可以配置Apache和nginx来做到这一点:通过告诉它们在HTTP头中设置“过期”日期,将其设置为未来很长时间:这样浏览器就知道:“好的,这个对象没有过时,因为我们还在过期日期之前”。

因此,当新用户访问Redmine时,他们的浏览器在第一页将获取.css和.js文件等,但在之后的页面上:不需要再次获取它们。

用户将体验到更快的网页构建速度!

Redmine的问题

不幸的是,Redmine(相当不明智地)使用.js文件名,用于包含用户内容的东西:即不应该在浏览器中缓存的东西。

这意味着;如果在Apache/nginx中添加一个简单的配置,来缓存所有名为*.js的东西:那么你的Redmine就会崩溃!

请参阅问题#17770 - 在那里报告了这个问题,看看Redmine团队是否可以将其更改为停止在错误的位置使用.js。

使用简单配置时,它会崩溃的地方有:(a) 在一期中编辑期刊时 (b) 在一期中上传文件时

Redmine的解决方案

简单情况,如上所述会破坏Redmine,因为它不关心js文件在哪个目录中:例如

location ~* \.(ico|css|js|gif|jp?g|png)(\?[0-9]+)?$ {
expires 365d;
}

因此需要使用更复杂的配置:在设置缓存标题之前,也会检查.js文件所在的目录。

我已经让这个工作起来了

        # the regex logic:   after either /javascripts/ or /stylesheets/ find the suffixes we want, followed by any quantity of numbers 0-9
        #     This works because the files we want to cache always appear after one of those 2 directories:  but not the files we want to ignore
        #        /journals/edit/24174.js   and /uploads.js?attachment_id=1&filename=my-file-to-upload.png
        location ~* /(?:(?:plugin_assets|themes).+)?(javascripts|stylesheets|images|favicon).+(css|js|jpg|gif|ico|png)(\?[0-9]+)$ {
            # add_header  X-SV-test 304-killer;    use this do-nothing HTTP Header, if you need to play with the regexp 
            #- for testing without fear of breaking anything!
            expires 365d;
        }

从redmine 3.4.0版本开始(#24617),静态文件请求会附加一个?timestamp,以避免在升级redmine版本时缓存服务错误文件的问题。然而,自定义主题不会附加时间戳到请求,因此application.css和responsive.css可能会异常崩溃。请参阅#29625以获取解决方案。

如果您想确保安全,请不要缓存没有?timestamp的文件

-  # the regex logic: after either /javascripts/ or /stylesheets/ find the suffixes we want, followed by any quantity of numbers 0-9
+  # the regex logic: after either /javascripts/ or /stylesheets/ find the suffixes we want, followed by one or more numbers 0-9
   # This works because the files we want to cache always appear after one of those 2 directories:  but not the files we want to ignore
   # /journals/edit/24174.js  and /uploads.js?attachment_id=1&filename=my-file-to-upload.png
-  location ~* /(?<file>/(?:(?:plugin_assets|themes).+)?(?:javascripts|stylesheets|images|favicon).+(?:css|js|jpe?g|gif|ico|png|html|woff|ttf|svg)(\?[0-9]+)?$) {
+  location ~* /(?<file>/(?:(?:plugin_assets|themes).+)?(?:javascripts|stylesheets|images|favicon).+(?:css|js|jpe?g|gif|ico|png|html|woff|ttf|svg)(\?[0-9]+)$) {

请注意,在nginx中:"expires"是设置对象"Expiry" HTTP头的配置。

在上面的例子中,365d表示365天。

有关nginx 'expires'配置的完整详细信息:https://nginxserver.cn/en/docs/http/ngx_http_headers_module.html#expires
对于Apache:请参阅mod_expires:https://httpd.apache.ac.cn/docs/2.2/mod/mod_expires.html

salman mp更新 12个月前 · 19次修订