revel静态资源必须放在public目录下且通过默认路由/public/*filepath服务,生产环境应由nginx代理,模板中需注入版本号避免缓存问题。

静态资源必须放在 public 目录下才能被 Revel 自动服务
Revel 不会自动扫描或映射任意路径下的静态文件。它只认一个固定位置:public/(项目根目录下),且该目录必须存在。所有 CSS、JS、图片等都得放进去,比如 public/css/app.css、public/js/main.js、public/images/logo.png。如果放错位置(如 assets/ 或 static/),即使加了路由也拿不到——因为 Revel 的默认静态文件处理器只监听 /public/*filepath 这条路由。
routes 文件里不能删掉或注释掉默认的静态路由
打开 conf/routes,你会看到类似这一行:
GET /public/*filepath Static.Serve
这是 Revel 提供的内置静态服务路由,它把所有以 /public/ 开头的请求转发给 Static.Serve 处理器。如果你删了、改了前缀(比如改成 /static/*filepath),或者把 Static.Serve 换成自定义 handler,那缓存控制、ETag、Gzip 压缩等默认行为都会失效——除非你手动重实现。
- 不要修改
/public/这个路径前缀;它和物理目录名强绑定 - 不要用
http.FileServer直接暴露public/目录——那样会绕过 Revel 的 filter 链,压缩、Cache-Control、ETag 全部不生效 - 若需额外静态路径(如上传文件),应单独加路由并自己处理,但别动这条默认规则
生产环境必须用 Nginx 反向代理接管静态资源
Revel 自带的 Static.Serve 仅适合开发。生产中直接用它服务静态文件,会丢失:HTTP/2 支持、Brotli 压缩、边缘缓存、连接限速、TLS 终止等关键能力。正确做法是让 Nginx 独立响应 /public/ 请求:
location ^~ /public/ {
alias /path/to/your/app/public/;
expires 1y;
add_header Cache-Control "public, immutable";
gzip_static on;
}
注意两点:
-
alias后路径末尾要带/,否则文件 404 - 必须用
^~前缀匹配,避免被后续正则 location 覆盖 - 此时 Revel 应用本身应监听
127.0.0.1:8089,不再对外暴露/public/路由(可从routes中注释掉那行,防止冲突)
模板中引用静态资源时别硬编码路径
在 app/views/ 下的模板里,写 <link rel="stylesheet" href="/public/css/app.css"> 是可行的,但不利于缓存失效。更稳妥的做法是结合版本号注入:
- 在
app.conf里加配置项:app.static_version = 20261016-abc123 - 用拦截器把该值注入模板上下文:
c.RenderArgs["staticVersion"] = revel.Config.StringDefault("app.static_version", "") - 模板中写:
<link rel="stylesheet" href="/public/css/app.css?v=%7B%7B.staticVersion%7D%7D">
这样每次发布新版本只需改配置,浏览器就会加载新资源。硬编码路径 + 强缓存,上线后用户大概率卡在旧 CSS 里,排查起来反而比改路径还费时间。











