Fiber 框架不自带 CORS 支持,必须手动注入中间件;用 cors.New() 最稳,手写易因 OPTIONS 404、Access-Control-Allow-Origin 与 AllowCredentials 冲突、header 设置过晚而失效。

直接结论:Fiber 框架不自带 CORS 支持,必须手动注入中间件;用 cors.New() 最稳,手写中间件极易因 OPTIONS 404、Access-Control-Allow-Origin 与 AllowCredentials: true 冲突、header 设置过晚而失效。
为什么 Fiber 手写 CORS 中间件常返回 404 或静默失败
Go 的 http.ServeMux(Fiber 底层仍依赖标准库的请求生命周期)对 OPTIONS 方法无默认路由逻辑,也不会 fallback 到你的 handler。如果你没在中间件里显式拦截 r.Method == "OPTIONS",请求就直接 404 —— 前端连预检都收不到。
- 必须在中间件开头判断:
if r.Method == "OPTIONS" { w.WriteHeader(http.StatusNoContent); return },不能调next.ServeHTTP() -
w.Header().Set()必须在w.WriteHeader()或首次w.Write()之前调用,否则 header 完全不发出去 - 若后端设了
Set-Cookie或前端 fetch 用了{ credentials: 'include' },Access-Control-Allow-Origin就不能是"*",否则浏览器静默丢弃响应(Network 面板里看不到 status)
用 fiber-contrib/cors 配置最省心
这是官方推荐的轻量中间件,自动处理 OPTIONS、header 注入时机、credentials 冲突校验等所有坑点。
- 安装:
go get github.com/gofiber/contrib/cors - 基础用法(允许指定源 + 凭据):
app.Use(cors.New(cors.Config{AllowOrigins: []string{"http://localhost:3000"}, AllowCredentials: true})) - 动态白名单(比如查数据库):
AllowOriginFunc: func(origin string) bool { return isInWhitelist(origin) },它会优先于AllowOrigins - 暴露自定义 header(如
X-Request-ID):ExposedHeaders: []string{"X-Request-ID"}
前端 Axios / Fetch 必须配对才能生效
后端开了 AllowCredentials: true,前端不配合,Cookie 和认证头照样发不出去。
- Axios:全局加
axios.defaults.withCredentials = true,或单个请求设{ withCredentials: true } - Fetch:必须显式传
{ credentials: 'include' },否则浏览器当普通跨域处理,不带 Cookie - CSRF 场景下,若同时启用
csrf.New(),还要确保前端从csrf_tokenCookie 里读值,并设到X-CSRF-Token请求头 —— 浏览器不会自动桥接这两个位置
真正容易被忽略的是:CORS 不是“开了就能用”,而是浏览器和服务器之间一整套严格匹配的协议。哪怕 AllowOrigins 里少写一个 https://,或 Nginx 反代时没透传 Origin 头,整个链路就断在预检阶段,且毫无提示。


















