beego跨域失败主因是allowcredentials与allowallorigins冲突、alloworigins未显式指定可信源、allowheaders/allowmethods配置不匹配、options路由未显式注册、cors filter插入时机错误(须用beforerouter)、servejson前header被覆盖或中间件干扰。

Beego 的跨域配置失败,八成是 cors.Allow 的参数没对上预检请求(OPTIONS)的实际需求,或者 AllowCredentials: true 和 AllowAllOrigins: true 冲突了——这两者不能共存,否则浏览器直接拒绝响应。
Beego 中 cors.Allow 的常见参数误配
很多人直接抄 “AllowAllOrigins: true + AllowCredentials: true”,但这是非法组合,浏览器会报错:A wildcard '*' cannot be used in the 'Access-Control-Allow-Origin' header when the credentials flag is true。必须显式列出可信源,且不能带通配符端口(如 "http://localhost:*" 在部分 Beego 版本中不生效)。
-
AllowOrigins应写具体协议+域名+端口,例如[]string{"http://localhost:5173", "https://myapp.com"};开发时可加"http://127.0.0.1:5173"(注意 localhost ≠ 127.0.0.1 在某些浏览器策略下) -
AllowHeaders必须包含前端实际发送的头,比如Content-Type、Authorization、Auth-Token—— 拼写大小写敏感,content-type和Content-Type在部分中间件里表现不同,建议统一用首字母大写形式 -
AllowMethods别写"*",尤其当后端没注册 OPTIONS 路由时,Beego 1.x 会 fallback 到 405;应明确列出[]string{"GET", "POST", "PUT", "DELETE", "OPTIONS"}
预检请求(OPTIONS)返回 405 或空白响应
浏览器发 OPTIONS 请求时,Beego 默认不会自动响应,除非你:① 注册了对应路由,或 ② 在全局 filter 中手动处理。只靠 cors.Allow 中间件,无法保证 OPTIONS 被正确捕获并返回 200。
- 在
router.go的init()函数里,加一条显式路由:beego.Router("/v1/:id", &controllers.APIController{}, "options:Options")(或通配beego.Router("/*", &controllers.BaseController{}, "options:Options")) - 在 controller 中实现
Options()方法,哪怕只写c.ServeJSON()也行,关键是让 Beego 执行到这一层,header 才会被 cors 中间件注入 - 如果用的是 Beego v2(
github.com/beego/beego/v2),确认导入的是github.com/beego/beego/v2/plugins/cors,旧版路径可能不兼容
JSON 响应失败但普通文本能过跨域
现象是浏览器控制台显示 “No 'Access-Control-Allow-Origin' header is present”,但 curl 或 Postman 看响应头里明明有——这说明跨域头被加了,但 Beego 在 ServeJSON() 之前提前写了 response body,导致 header 被忽略。根本原因是 filter 执行时机不对。
- 务必使用
beego.BeforeRouter而非beego.BeforeExec插入 CORS filter,否则 filter 可能在路由匹配前就失效 - 避免在 controller 方法开头手动调用
c.Ctx.ResponseWriter.Header().Set(...),它会覆盖 cors 中间件设置的值;所有跨域头应由cors.Allow统一管理 - 检查是否启用了
EnableGzip或其他中间件,它们可能干扰 header 写入顺序;临时关闭测试可快速定位
最易被忽略的一点:Beego 的 cors.Options 中 ExposeHeaders 不影响跨域许可,只决定前端 JS 能读取哪些响应头;如果你前端要读 X-Total-Count 这类自定义头,就必须把它加进 ExposeHeaders,否则 JS 拿不到,但请求本身不会失败。











