静态文件404不是模板引擎问题,而是未显式调用app.Static("/static", "./public")——Fiber默认不处理/static路径,仅响应注册的路由和c.Render()。

静态文件 404 不是模板引擎的问题,而是你没配 app.Static —— Fiber 默认完全不处理 /static/style.css 这类请求,它只管路由匹配和 c.Render()。
为什么 app.Static() 必须显式调用
Fiber 的中间件是“挂载制”,不是“接管制”。app.Static 不是自动扫描目录的后台服务,它是一个路由处理器,只响应你指定前缀下的 GET 请求,并按路径映射到本地文件系统。
- 没调用
app.Static("/static", "./public")→ 浏览器请求/static/main.css直接 404(Fiber 根本不认这个路径) - 写成
app.Use(static.New("./public"))(无路径前缀)→ 所有请求(包括/login、/api/users)都会先被 static 尝试匹配,性能下降且可能覆盖业务路由 -
app.Static("/assets", "./public")→ 只对/assets/logo.png生效,/static/logo.png仍 404
SPA 场景下刷新 404 怎么办
单页应用(如 Vue/React)依赖前端路由,但浏览器刷新时会向后端发真实请求,比如访问 /dashboard/settings,Fiber 默认找不到该路由就返回 404。
解决方式是启用 Index 回退:让所有未命中路由的请求,都 fallback 到 index.html,由前端路由接管。
- 必须显式设置
Index: "index.html",默认值是空字符串,不生效 - 正确写法:
app.Static("/static", "./public", fiber.Static{ Index: "index.html", }) - 注意:这仅对
/static/xxx路径生效;若 SPA 前端部署在根路径(/),应改用app.Static("/", "./public", ...),但更推荐单独用app.Get("*", ...)处理兜底
常见配置陷阱与参数差异
fiber.Static 结构体里几个字段容易误用,错一个就静默失效:
-
Browse默认false;设为true会开启目录列表,但若同时开了Index,可能意外暴露./public/config/下的敏感结构 -
Compress默认false;设为true启用 gzip,但必须放在compress.New()中间件之后,否则无效(compress中间件不可置于static前) -
MaxAge控制 Cache-Control 的max-age秒数,单位是秒(不是 time.Duration),填3600表示 1 小时,别写成time.Hour -
Download设为true会强制触发浏览器下载而非渲染,适合提供/download/report.pdf这类接口
最易被忽略的一点:路径映射是严格字面匹配的。如果你写 app.Static("/static", "./assets"),而文件实际在 ./public/css/app.css,那无论如何都加载不到——Fiber 不递归查找,也不做路径重写。目录结构和挂载路径必须对齐。


















