应使用 app.FileServer("/", iris.Dir("./dist")) 托管 ./dist;若部署子路径如 /admin/,需设 publicPath: "/admin/" 并配 app.FileServer("/admin", iris.Dir("./dist"));避免与 app.StaticWeb 混用,且 catch-all 路由须置于静态路由之后。

如何用 app.FileServer 正确托管静态资源
直接暴露 ./dist 目录是最常见做法,但必须配对使用 iris.Dir 和正确的路径映射。Iris 不会自动推断你希望把 index.html 当作入口,也不会默认启用目录索引 —— 这是好事,避免误暴露文件结构。
常见错误:只写 app.FileServer("/static", "./dist"),结果 JS/CSS 路径 404。原因在于前端构建时 publicPath 默认为 /,而你却把资源挂载到了 /static/ 下,浏览器请求的是 /js/app.js,但服务端只在 /static/js/app.js 才能命中。
- 若前端构建输出在
./dist,且publicPath: "/",应使用app.FileServer("/", iris.Dir("./dist")) - 若部署在子路径(如
/admin/),需改publicPath: "/admin/",并配app.FileServer("/admin", iris.Dir("./dist")) - 别同时启用
app.StaticWeb和app.FileServer,后者会覆盖前者,且容易因路径重叠引发 404
/{path:path} 通配路由和静态资源的冲突点
SPA 路由的 catch-all 写法本身不加载静态文件,它只是兜底返回 index.html。但如果你在它之前没关掉 Iris 的默认静态服务,或路径规则顺序不对,/js/app.js 就可能被 /{path:path} 拦截并返回 HTML,造成 MIME 类型错乱、控制台报错“Unexpected token
验证是否冲突:直接 curl http://localhost:8080/js/app.js,响应头 Content-Type 应为 application/javascript,内容应是 JS 代码;如果返回 HTML 片段,说明通配规则劫持了静态请求。
- 务必把
app.FileServer注册在app.Handle("GET", "/{path:path}", ...)之前 - 检查是否无意调用了
app.StaticWeb或app.StaticEmbedded,它们会注册内部静态路由,与通配冲突 - 生产环境建议禁用所有自动静态服务:
app.Configure(iris.WithoutVersionChecker, iris.WithoutServerError(iris.ErrLog))中加iris.WithoutStaticHandler
嵌入资源(embed.FS)与 app.FileServer 的取舍
Go 1.16+ 支持 embed.FS,适合将前端产物打包进二进制。Iris 提供 app.FS 方法直接对接,比 app.FileServer 更轻量、无文件系统依赖。
但要注意:嵌入后路径是只读的,无法热更新;且 embed.FS 不支持动态目录遍历,必须显式声明所有文件(或用 //go:embed dist/* 通配),否则 index.html 引用的 favicon.ico 可能 404。
- 嵌入写法示例:
var assets embed.FS<br>app.FS("/", iris.Embed(assets, "./dist")) - 嵌入后仍需处理 SPA 路由:嵌入版的
index.html仍要靠/{path:path}回退,不能省略 - 调试阶段优先用
app.FileServer,上线前再切到embed,避免本地开发时反复编译二进制
反向代理场景下 Iris 该不该管静态资源
当 Nginx / Caddy 托管 ./dist 并反代 API 请求到 Iris 时,Iris 就不该再碰任何静态文件 —— 包括 app.FileServer、app.StaticWeb、甚至 /{path:path} 对非 API 路径的兜底。
否则会出现:Nginx 正确返回 /css/main.css,但用户刷新 /user/profile 时,Iris 的通配路由抢先响应了 index.html,而 Nginx 没机会接管,导致页面白屏或资源路径错乱。
- 此时 Iris 只保留 API 路由,
/{path:path}应严格限定在 API 前缀之外,例如:if !strings.HasPrefix(ctx.Request().URL.Path, "/api/") { ... } - 确保 Nginx 配置中,
location /先尝试找文件,找不到才proxy_pass到 Iris - 最保险的做法:Iris 完全不注册任何静态相关 handler,把全部静态职责交给反向代理
真正麻烦的从来不是怎么写那几行代码,而是搞清「谁该负责哪段路径」——静态资源归属一旦模糊,404 就会出现在最意想不到的地方,比如 favicon、manifest.json 或预加载的字体文件。


















