fiber框架中必须显式注册cors中间件,fiber.new()不自带跨域支持,需用github.com/gofiber/contrib/cors并调用app.use(cors.new()),否则options预检失败、响应头无效或浏览器静默拦截。

fiber.New() 启动后必须手动加 CORS 中间件
Fiber 不像 Gin 那样自带 gin-contrib/cors 的开箱即用集成,fiber.New() 返回的是空应用,所有中间件(包括 CORS)都得显式注册。别指望 fiber.Default() —— 它带的默认中间件不处理跨域,而且日志/panic 恢复还会泄露敏感头、拖慢 TTFB。
常见错误是直接在 handler 里写:c.Set("Access-Control-Allow-Origin", "*"),这完全无效:CORS 需要预检响应、OPTIONS 拦截、header 设置时机控制,单靠 c.Set() 只对主请求生效,OPTIONS 仍会 404 或返回空响应。
- 必须用
github.com/gofiber/contrib/cors(不是gorilla/handlers.CORS,后者不兼容 Fiber 的fiber.Ctx) - 安装命令:
go get github.com/gofiber/contrib/cors - 注册方式:
app.Use(cors.New(cors.Config{...})),不能只在某个路由上用app.Get("/api", cors.New(...), handler),否则 OPTIONS 请求进不来
AllowOrigins 和 AllowCredentials 别同时设为 * + true
AllowOrigins: []string{"*"} 和 AllowCredentials: true 共存,浏览器会静默丢弃整个响应——Network 面板里连 status 都看不到,只显示“Failed to load resource”。这不是你的服务挂了,是浏览器按规范强制拦截。
真正需要带 Cookie 或 Authorization 的场景(比如登录态校验),必须指定具体域名:
- ✅ 正确:
AllowOrigins: []string{"https://myapp.com", "http://localhost:3000"}+AllowCredentials: true - ❌ 错误:
AllowOrigins: []string{"*"}+AllowCredentials: true - ⚠️ 动态白名单?用
AllowOriginFunc,例如检查子域名或从数据库查 origin 是否合法
OPTIONS 请求必须被中间件提前拦截,不能落到业务 handler
如果前端发的是带自定义 header(如 X-Auth-Token)或非简单方法(如 PUT/DELETE),浏览器会先发 OPTIONS 预检。Fiber 默认不处理 OPTIONS 方法,若中间件没拦截,请求就直接 404 或进入你写的 app.Put() handler —— 但此时 c.Method 是 OPTIONS,你没做判断,就会返回 404 或错误内容。
gofiber/contrib/cors 内部已自动处理:收到 OPTIONS 请求时,直接写响应并 return,不调用 c.Next()。你不需要、也不应该在 handler 里手动判断 c.Method == "OPTIONS"。
- 别在 handler 里写:
if c.Method == "OPTIONS" { c.SendStatus(204); return }—— 这容易漏掉中间件链、header 冲突或重复设置 - 暴露自定义响应头?加
ExposedHeaders: []string{"X-Request-ID", "X-Total-Count"} - 允许哪些请求头?明确列出来:
AllowHeaders: []string{"Content-Type", "Authorization", "X-Auth-Token"},别偷懒写"*"(浏览器不认)
开发和生产环境的 Origin 配置差异要硬隔离
本地开发时常用 http://localhost:3000,上线后是 https://app.example.com。把两者混在同一个 AllowOrigins 列表里,等于把生产环境暴露给任意本地端口——攻击者起个 http://localhost:3001 就能绕过限制。
推荐做法是读环境变量动态构造白名单:
- 开发:
os.Getenv("ENV") == "dev"→AllowOrigins: []string{"http://localhost:3000"} - 生产:
os.Getenv("ENV") == "prod"→AllowOrigins: []string{"https://app.example.com"} - 测试环境可额外加 CI 预览地址,但禁止用
"*"或模糊匹配(如"http://*.example.com")
最易被忽略的一点:Fiber 的 cors 中间件不会自动处理 WebSocket 升级请求的跨域。/ws 路由必须单独配 websocket.New() 并启用 CheckOrigin,否则前端连不上 ws:// 服务。











