fiber.CORS()必须在路由注册前调用,因Fiber中间件链严格按注册顺序执行,后注册的中间件无法包裹已定义路由;若AllowCredentials为true,则AllowOrigins不能为"*",须指定完整域名列表,否则浏览器静默拦截。

fiber.CORS() 必须在注册任何路由前调用,否则对已定义的路由完全无效。
为什么 app.Use(fiber.CORS()) 放错位置就失效
Fiber 的中间件链是严格顺序执行的:只有在 app.Use() 之后注册的路由才会被该中间件包裹。如果你先写 app.Get("/api/user", handler),再调用 app.Use(fiber.CORS()),那这个 GET 路由根本不会经过 CORS 中间件。
- 正确顺序:初始化 app →
app.Use(fiber.CORS())→ 再注册所有app.Get()、app.Post()等 - 常见错误现象:前端控制台报
No 'Access-Control-Allow-Origin' header,但后端日志里明明有请求——说明 CORS 没生效,请求压根没被中间件处理 - 验证方法:在
fiber.CORS()前加个app.Use(func(c *fiber.Ctx) error { log.Println("CORS middleware hit"); return c.Next() }),看是否打日志
AllowCredentials: true 时 AllowOrigins 不能写 "*"
浏览器硬性规定:一旦响应头含 Access-Control-Allow-Credentials: "true",Access-Control-Allow-Origin 就不能是通配符 "*",否则静默拦截,连控制台错误都不报。
- 必须显式列出完整协议+域名+端口,例如
[]string{"https://app.example.com", "http://localhost:3000"} -
https://*.example.com或https://example.com:*不合法,Fiber 不支持子域通配 - 若前端 fetch 设置了
{ credentials: 'include' },后端配置漏掉AllowCredentials: true或AllowOrigins不匹配,结果都是空响应体或 401
OPTIONS 预检失败的三个关键点
fiber.CORS() 自动处理 OPTIONS 请求,但容易被其他逻辑干扰导致 404/405 或响应体非空。
使用 uber-go/dig 在 Golang 中实现依赖注入——基于反射容器,提供 Provide/Invoke、dig.In/dig.Out 参数与结果对象,支持命名依赖等
- 确保没有前置中间件(如鉴权、日志)在
c.Next()前调用c.Status(401).Send()或c.SendStatus()—— 这会提前终止请求,让预检走不到 CORS 逻辑 - 不要手动注册
app.Options()路由;fiber.CORS()已内置拦截,重复注册反而可能覆盖其 204 响应 - 如果启用了
StrictRouting: true,预检路径必须和业务路径完全一致(比如GET /api/user对应的预检必须是OPTIONS /api/user,不是OPTIONS /api/user/)
暴露自定义响应头和生产环境最小化配置
前端想读 response.headers.get("X-Total-Count") 却返回 null?大概率是漏了 ExposeHeaders。
-
ExposeHeaders必须显式声明所有非简单头(Content-Type、Cache-Control等除外),例如ExposeHeaders: []string{"X-Total-Count", "X-Request-ID", "X-RateLimit-Remaining"} - 生产环境禁用默认配置:不要用
fiber.CORS()无参调用,至少指定AllowOrigins、AllowMethods(如"GET,POST,PUT,DELETE,OPTIONS")、AllowHeaders(至少含"Content-Type,Authorization") -
MaxAge设为 3600 可缓存预检结果,避免每个请求都触发 OPTIONS
最易忽略的是 ExposeHeaders 和 Vary: Origin —— 前者导致前端拿不到自定义头,后者缺失会让 CDN 或代理缓存错误的 CORS 响应,同一缓存键下把 Origin: https://a.com 的响应发给了 https://b.com 的请求。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!










