Revel 框架不内置 CORS 支持,需手动配置:可在 action 中设响应头、用 Filter 实现全局中间件,或在 Nginx 层添加 CORS 头;同时必须正确透传 X-Forwarded-Proto 以保障 Session 安全性。

Revel 框架本身不内置 CORS 中间件,也不自动设置 Access-Control-Allow-Origin 等响应头——跨域必须由你显式配置,否则前端发请求会直接被浏览器拦截,报错 No 'Access-Control-Allow-Origin' header is present。
Revel 应用层手动注入 CORS 响应头
Revel 的 HTTP 处理链中没有默认 CORS 支持,最直接的方式是在每个需要跨域的 action 里手动写响应头。这种方式控制粒度细,适合少量接口或调试阶段。
- 在 controller 方法开头调用
c.Response.Out.Header().Set()设置必要头:
func (c App) MyApi() revel.Result {
c.Response.Out.Header().Set("Access-Control-Allow-Origin", "https://your-frontend.com")
c.Response.Out.Header().Set("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS")
c.Response.Out.Header().Set("Access-Control-Allow-Headers", "Content-Type, Authorization, X-Requested-With")
c.Response.Out.Header().Set("Access-Control-Allow-Credentials", "true")
// 注意:若前端带 Cookie,Origin 不能为 *,且必须设 Allow-Credentials
return c.RenderJSON(map[string]string{"status": "ok"})
}
- 对
OPTIONS预检请求必须单独处理,否则浏览器卡在预检阶段,返回 405 或静默失败;可在App.Init()或全局 filter 中拦截: - 务必检查
c.Request.Method == "OPTIONS",并返回空体 + 204 状态码
用 Revel Filter 实现全局 CORS 中间件
手动加头太重复,推荐用 Revel 的 Filter 机制统一处理。Filter 在 request 进入 action 前执行,能覆盖所有路由(包括静态资源),但要注意执行顺序和 OPTIONS 特殊性。
- 在
app/init.go的init()函数中注册 filter,位置要早于REVEL_INTERCEPTOR(建议放在revel.BEFORE_ROUTER或revel.BEFORE_ACTION) - filter 函数内先判断是否为
OPTIONS请求,是则立即return nil(不进 action),并手动写响应头 + 204 - 非 OPTIONS 请求,在
filterChain.Continue(req, resp)后再写响应头(确保 response 尚未 flush) - 注意:不要在 filter 中调用
c.Render或类似方法,会干扰后续流程
Nginx 层代理时配置 CORS(绕过 Revel)
如果你已用 Nginx 反向代理 Revel(如 proxy_pass http://127.0.0.1:8089),那完全可以在 Nginx 配置里加 CORS 头——这比改代码更轻量、更安全,尤其适用于多后端共用一套前端域名的场景。
- 在
location块中添加如下头(注意:必须放在proxy_pass同级,不能嵌套在 if 里):
add_header 'Access-Control-Allow-Origin' 'https://your-frontend.com' always; add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE, OPTIONS' always; add_header 'Access-Control-Allow-Headers' 'Content-Type, Authorization, X-Requested-With' always; add_header 'Access-Control-Allow-Credentials' 'true' always; # 必须加 always,否则 204/304 响应不带 CORS 头
- 同时确保 Nginx 正确透传原始协议(
X-Forwarded-Proto),否则 Revel 的Session().Get()在 HTTPS 下可能失效 - 此方式下 Revel 完全无感知,也无需处理 OPTIONS;但无法动态白名单(除非用 Lua 模块)
为什么不能只靠 proxy_redirect 或忽略 X-Forwarded-Proto
Revel 依赖 X-Forwarded-Proto 判断当前是否为 HTTPS,进而决定 Session Cookie 的 Secure 标志位。如果 Nginx 没传这个头,即使走的是 HTTPS 域名,Revel 仍按 HTTP 处理,导致 Session().Get() 返回空或报错;而 proxy_redirect 是重写 Location 响应头用的,Revel 自己已处理 302 重定向,额外启用反而可能破坏跳转逻辑。
真正容易被忽略的是:CORS 白名单与 Session 安全性是一体两面——允许凭据(credentials: true)就必须指定明确 Origin,不能用 *;而这个 Origin 值又必须和 Nginx 传给 Revel 的 X-Forwarded-Proto 协议一致,否则前端连 Cookie 都发不过去。


















