Buffalo框架在生产模式下默认为/assets资源注入Cache-Control: public, max-age=31536000强缓存头;开发时需手动禁用:改用裸http.FileServer并设置no-cache响应头,或强制设GO_ENV=development,同时排查CDN/Nginx等反向代理层缓存。

Buffalo 框架默认会加 Cache-Control: public, max-age=31536000
这是 Buffalo 在生产模式(GO_ENV=production)下自动为静态资源(如 /assets/ 下的 JS/CSS/图片)注入的强缓存头,目的是提升前端加载性能。但开发时或灰度发布阶段,这会导致浏览器死活不拉新文件——你改了 app.css,页面还是旧样式,F5 无效,硬刷也无效。
buffalo.New() 中关闭 AssetFS 的自动缓存
Buffalo 的静态资源服务由 http.FileServer 包裹的 AssetFS 提供,默认启用了缓存中间件。禁用的关键是绕过它自带的缓存包装逻辑:
- 在
app.go初始化 app 后,找到类似app.Use(middleware.AssetHandler())或app.ServeFiles("/assets", http.Dir("public/assets"))的代码 - **不要**直接用
app.ServeFiles,改用裸http.FileServer并手动设置 Header:
fs := http.FileServer(http.Dir("public/assets"))
http.Handle("/assets/", http.StripPrefix("/assets/", fs))
// 禁用缓存:对所有 /assets/ 请求清除 Cache-Control 并设为 no-cache
http.HandleFunc("/assets/", func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Cache-Control", "no-cache, no-store, must-revalidate")
w.Header().Set("Pragma", "no-cache")
w.Header().Set("Expires", "0")
fs.ServeHTTP(w, r)
})
注意:这段代码必须放在 app.ServeFiles 或 middleware.AssetHandler() **之前**,否则会被覆盖。
开发环境强制禁用:改 actions/render.go 的 ENV 判断
Buffalo 的 AssetHandler 内部会检查 env.IsProduction() 决定是否加缓存头。最简单粗暴的方式是让开发环境也走“非生产”路径:
- 打开
grifts/init.go或actions/app.go,确认env.Load()是否被调用 - 确保
GO_ENV环境变量没被误设为production(比如 shell 里 export 过忘了清) - 如果仍不行,在
app.go初始化前加一句:os.Setenv("GO_ENV", "development")(仅限本地调试)
这个方法治标不治本,但能快速验证是不是缓存头惹的祸。
Buffalo框架 1.0.1 版本源码包下载,适合需要错误处理改进、依赖更新、render.Download 注释和 request logger 调整的 v1 项目。
CDN 或反向代理层也在缓存?查 X-Cache 和真实响应头
即使 Buffalo 层禁用了,Nginx、Cloudflare 或 k8s Ingress 可能还在缓存。用 curl 看真实响应头:
curl -I https://yoursite.com/assets/app.js
重点看:Cache-Control、Age、X-Cache(Nginx)、Cf-Cache-Status(Cloudflare)。如果这些字段显示 HIT 或有 long max-age,问题就不在 Buffalo 本身。
嵌入式资源和反向代理缓存是两个独立层级,Buffalo 控不了 Nginx 的 proxy_cache,这点容易忽略。










