cors.New() 是 Fiber 处理跨域的唯一推荐方式,因其自动处理预检(OPTIONS)、凭证兼容与头合并;手写响应头仅覆盖简单请求,遇预检将 404/500,且易错配 AllowOrigins、AllowCredentials 与 AllowHeaders 字段。

cors.New() 是 Fiber 处理跨域的唯一推荐方式,直接写响应头或自定义中间件不仅重复造轮子,还会漏掉预检(OPTIONS)处理、凭证兼容、头合并等关键逻辑。
为什么不能手写 c.Header("Access-Control-Allow-Origin", "*")
浏览器对跨域请求分两类:简单请求(如 GET + text/plain)和预检请求(含 Authorization、Content-Type: application/json 等)。手写头只覆盖前者,遇到预检会直接 404 或 500;cors.New() 自动拦截 OPTIONS 并返回 204,同时校验方法、头、凭据三者一致性。常见错误现象是前端报 “No 'Access-Control-Allow-Origin' header is present”,其实后端已返回数据,但因为没处理预检,浏览器根本没发主请求。
cors.Config 里最容易填错的三个字段
配置结构体字段名大小写敏感,空值含义反直觉:
-
AllowOrigins是字符串切片,不是单个字符串:[]string{"https://a.com", "https://b.com"};写成"*"时,AllowCredentials必须为false,否则中间件静默跳过(无 panic、无日志) -
AllowCredentials默认false,设为true后,AllowOrigins不能再用"*",必须显式列出完整协议+域名+端口(比如"https://a.com:8080"),尾部斜杠也参与匹配 -
AllowHeaders默认为空,不继承请求头;若前端带X-Auth-Token,就必须写进列表:AllowHeaders: []string{"Content-Type", "Authorization", "X-Auth-Token"}
中间件挂载位置决定生效范围
app.Use() 的第一个参数是路径前缀,不是“过滤器”——它只对匹配该前缀的请求执行,且不自动透传到子路径外:
-
app.Use("/api", cors.New())→ 只作用于/api/users、/api/v1/posts,/health或/不走 CORS -
app.Use(cors.New())(无前缀)→ 全局生效,包括/favicon.ico、/robots.txt,可能干扰监控采集 - 若需部分路由禁用 CORS(如公开静态资源),得用路由级绑定:
app.Get("/public/*", func(c *fiber.Ctx) error { return c.Next() }),再把cors.New()放在其他路由前
生产环境必须显式控制 origin 白名单
开发阶段用 AllowOrigins: []string{"*"} 速测可以,上线必须精确匹配。动态多租户场景别用 AllowOriginsFunc: func(origin string) bool { return true },应解析 c.Host() 或 c.Get("Origin") 后做白名单比对。更安全的做法是结合 Nginx 做前置校验,Fiber 层只处理已放行的请求——因为 cors.New() 对非法 origin 只是不写头,不会主动拒绝,浏览器仍会收到 200 但无法读响应。


















