中间件
CORS 跨域
ReleaseAllCors 和 AllowOption 处理跨域请求
CORS 跨域
xMiddle 提供两个中间件处理跨域请求:ReleaseAllCors 设置 CORS 头部,AllowOption 处理预检请求。
ReleaseAllCors
设置跨域请求的 HTTP 头部信息,允许所有来源:
func ReleaseAllCors(ctx *gin.Context)实现:
func ReleaseAllCors(ctx *gin.Context) {
ctx.Writer.Header().Set("Access-Control-Allow-Origin", "*")
ctx.Writer.Header().Set("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS")
ctx.Writer.Header().Set("Access-Control-Allow-Headers", "Content-Type, Authorization")
ctx.Next()
}设置的头部
字段
类型
AllowOption
处理 CORS 预检请求(OPTIONS 方法),直接返回 200 状态码并终止请求链:
func AllowOption(ctx *gin.Context)实现:
func AllowOption(ctx *gin.Context) {
if ctx.Request.Method == "OPTIONS" {
xLog.WithName(xLog.NamedMIDE).Debug(ctx, "检测到 OPTIONS 请求,继续处理")
ctx.AbortWithStatus(200)
}
}特性:
- 检测请求方法是否为
OPTIONS - 记录 Debug 级别日志(使用
NamedMIDE标识) - 返回 HTTP 200 并终止后续中间件执行
使用示例
基础使用
func main() {
router := gin.Default()
// 先设置 CORS 头,再处理 OPTIONS
router.Use(xMiddle.ReleaseAllCors)
router.Use(xMiddle.AllowOption)
router.GET("/api/users", getUsers)
router.Run(":8080")
}执行流程
自定义 CORS
生产环境建议自定义 CORS 配置:
func CustomCors(allowedOrigins []string) gin.HandlerFunc {
return func(ctx *gin.Context) {
origin := ctx.Request.Header.Get("Origin")
// 检查是否在允许列表中
for _, allowed := range allowedOrigins {
if origin == allowed {
ctx.Writer.Header().Set("Access-Control-Allow-Origin", origin)
break
}
}
ctx.Writer.Header().Set("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS")
ctx.Writer.Header().Set("Access-Control-Allow-Headers", "Content-Type, Authorization")
ctx.Writer.Header().Set("Access-Control-Allow-Credentials", "true")
ctx.Next()
}
}使用:
router.Use(CustomCors([]string{
"https://example.com",
"https://app.example.com",
}))
router.Use(xMiddle.AllowOption)注意事项
中间件顺序
// 正确顺序:先 CORS,后 OPTIONS
router.Use(xMiddle.ReleaseAllCors) // 1. 设置头部
router.Use(xMiddle.AllowOption) // 2. 处理预检开发 vs 生产
| 环境 | 推荐配置 |
|---|---|
| 开发环境 | ReleaseAllCors(允许所有来源) |
| 生产环境 | 自定义 CORS(限制允许的来源) |
携带凭证
如果需要携带 Cookie,需要自定义 CORS:
// ReleaseAllCors 使用 "*",不支持 credentials
// 需要自定义中间件设置具体的 Origin
ctx.Writer.Header().Set("Access-Control-Allow-Credentials", "true")