Beego配置CORS必须同时满足三件事:正确路由并响应OPTIONS预检请求、响应头严格匹配浏览器要求、AllowCredentials与AllowOrigins不冲突;仅配过滤器或只写options()方法易失败。

Beego 配置 CORS 跨域请求,核心不是“加个过滤器就行”,而是必须同时满足三件事:预检(OPTIONS)请求能被正确路由并响应、响应头字段严格匹配浏览器要求、AllowCredentials 与 AllowOrigins 不冲突。只配中间件或只写一个 options() 方法,大概率失败。
预检请求(OPTIONS)必须被路由捕获并返回 200
浏览器对非简单请求(如带 Authorization、Content-Type: application/json)会先发 OPTIONS 请求。如果 Beego 没有为对应路径注册 OPTIONS 处理器,就会返回 405 或 404,跨域直接中断。
- 不能只靠
cors.Allow()插件自动处理 —— 它只加 header,不接管路由 - 必须显式注册
OPTIONS方法,例如:beego.Router("/api/user", &controllers.UserController{}, "options:Options") - 或者用命名空间统一注册:
ns := beego.NewNamespace("/v1", beego.NSRouter("*", &controllers.BaseController{}, "options:Options"), ) -
Options()方法体里只需设置 status 200,无需返回 body,但必须调用c.ServeJSON()或c.Ctx.ResponseWriter.WriteHeader(200)
AllowCredentials = true 时,AllowOrigins 不能是 "*"
这是最常踩的坑:一旦启用凭证(如 Cookie、withCredentials: true),浏览器明确拒绝 Access-Control-Allow-Origin: *,会报错 A wildcard '*' cannot be used in the 'Access-Control-Allow-Origin' header when the credentials flag is true。
- 必须用白名单方式指定源:
AllowOrigins: []string{"http://localhost:8080", "https://myapp.com"} - 支持通配符子域名(需 Beego ≥ 2.1):
AllowOrigins: []string{"https://*.example.com"} - 开发时可用正则匹配本地多端口:
AllowOrigins: []string{"http://localhost:[0-9]{4}"}(需自行在 filter 中解析 Origin 并校验) - 若必须兼容任意源且带凭证,只能改前端——去掉
withCredentials,或后端改用 token 放 header 传
AllowHeaders 必须包含客户端实际发送的所有非简单头
错误信息 Request header field X is not allowed by Access-Control-Allow-Headers 就是因为这个。浏览器把你在请求中手动加的 header(比如 Auth-Token、X-Trace-ID)全列在 Access-Control-Request-Headers 里发给服务端,Beego 必须原样出现在 AllowHeaders 中。
- 不要写
"*"—— Beego 的cors插件不支持通配符值(Go 标准库也不允许) - 常见漏项:
Content-Type(注意大小写)、Authorization、Accept、X-Requested-With - Vue/Angular 默认加
Accept和Content-Type;Axios 默认加Accept和Content-Type;fetch 若设headers: { "X-App": "v1" },就必须加"X-App" - 示例配置:
AllowHeaders: []string{"Origin", "Content-Type", "Authorization", "Accept", "X-App", "X-Trace-ID"}
用官方 cors 插件还是手写 filter?看场景
两者都能用,但行为差异明显:插件更省事但灵活性低;手写 filter 更可控但容易漏 header 或状态码。
- 用
github.com/astaxie/beego/plugins/cors适合快速上线、源固定、不带复杂 header 的项目 - 手写 filter 适合需要动态 Origin 校验(如从 DB 查白名单)、或要兼容旧版 Beego(
- 手写时务必注意:
c.Ctx.ResponseWriter.Header().Set()必须在c.ServeJSON()前调用,否则 header 会被覆盖 - 别在 controller 里 set header —— 此时 response 已开始写入,header 设置无效
真正麻烦的不是配置本身,而是浏览器预检失败时只报 CORS 错误,不告诉你具体哪条 header 不匹配、哪个 origin 被拒、甚至 OPTIONS 是否根本没走到你的代码里。建议用 curl 模拟预检请求验证:curl -I -X OPTIONS -H "Origin: http://localhost:8080" -H "Access-Control-Request-Method: POST" http://your-api/v1/login,看响应头是否完整。


















