本文详解 gin 中 cors 中间件的常见错误与正确写法,重点解决 options 预检请求后无响应、跨域失败等问题,提供可直接使用的健壮中间件实现及关键配置说明。
在使用 Gin 构建 Web API 时,前端(如 React/Vue)发起跨域请求常触发浏览器的 CORS 预检(Preflight)机制——即先发送一个 OPTIONS 请求,待服务端明确允许后,才执行真正的 GET/POST 等请求。若中间件处理不当,即使返回了 200 OK,也可能因响应体缺失、状态码不规范或头信息冲突导致预检失败,表现为“请求静默终止”或控制台报错 CORS header ‘Access-Control-Allow-Origin’ missing。
以下是一个生产可用、符合 W3C CORS 规范的 Gin CORS 中间件实现:
func CORSMiddleware() gin.HandlerFunc {
return func(c *gin.Context) {
// 允许任意源(开发环境可用;生产环境建议指定明确域名,如 "https://your-app.com")
c.Header("Access-Control-Allow-Origin", "*")
// 允许携带认证信息(cookies、Authorization header等),注意:Allow-Origin 不能为 "*" 时才可设为 true
c.Header("Access-Control-Allow-Credentials", "true")
// 明确声明允许的请求头,需覆盖前端实际发送的所有自定义 Header(如 Authorization、X-Requested-With)
c.Header("Access-Control-Allow-Headers", "Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, Authorization, accept, origin, Cache-Control, X-Requested-With")
// 声明允许的 HTTP 方法
c.Header("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE, PATCH")
// 关键:OPTIONS 请求必须立即终止链路,并返回 204 No Content(非 200)
// 浏览器要求预检响应不能包含 body,204 是语义最准确的状态码
if c.Request.Method == "OPTIONS" {
c.AbortWithStatus(204)
return
}
c.Next()
}
}
? 重要注意事项: