You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Gin框架非简单请求(POST JSON)的CORS问题求解,多种方案失效

问题

在localhost:8080部署的网站,通过Axios访问localhost:9999上的Gin服务器时,GET请求正常,但POST请求始终报CORS错误:

Access to XMLHttpRequest at 'http://127.0.0.1:9999/inlog/' from origin 'http://127.0.0.1:8080' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.

已尝试三种CORS配置方案,但均无效,代码如下:

func main() {
    r.Use(cors.Default())
    //r.Use(Cors())
    //r.Use(Cors1())
    r.Use(Cors3())
    r.POST("/inlog", func(c *gin.Context) {
        print(c)
        c.JSON(200, gin.H{"status": "OK", "message": "pong",})
    })

    r.GET("/ping", func(c *gin.Context) {
        c.JSON(200, gin.H{
            "message": "pong",
        })
    })
    r.Run(":9999")
}

func Cors() gin.HandlerFunc {
    return cors.New(cors.Config{
        AllowAllOrigins:  true,
        AllowMethods:     []string{"POST", "GET", "PUT", "DELETE", "OPTIONS"},
        AllowHeaders:     []string{"*"},
        ExposeHeaders:    []string{"Content-Length", "Authorization", "Content-Type"},
        AllowCredentials: true,
        MaxAge:           12 * time.Hour,
    },
    )
}

func Cors1() gin.HandlerFunc {
    return func(c *gin.Context) {
        method := c.Request.Method
        origin := c.Request.Header.Get("Origin")
        if origin != "" {
            c.Header("Access-Control-Allow-Origin", origin)
            c.Header("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE, UPDATE")
            c.Header("Access-Control-Allow-Headers", "Content-Type,AccessToken,X-CSRF-Token, Authorization")
            c.Header("Access-Control-Allow-Credentials", "true")
            c.Header("Access-Control-Expose-Headers", "Content-Length, Access-Control-Allow-Origin, Access-Control-Allow-Headers,Cache-Control,Content-Language,Content-Type,Expires,Last-Modified,Pragma,FooBar")
        }
        if method == "OPTIONS" {
            c.Header("Access-Control-Allow-Origin", origin)
            c.Header("Access-Control-Allow-Methods", "OPTIONS")
            c.Header("Access-Control-Allow-Headers", "*")
            c.AbortWithStatus(http.StatusNoContent)
        }
        c.Next()
    }
}

func Cors3() gin.HandlerFunc {
    return func(context *gin.Context) {
        method := context.Request.Method
        context.Header("Access-Control-Allow-Origin", "*")
        context.Header("Access-Control-Allow-Headers", "Content-Type,AccessToken,X-CSRF-Token, Authorization, Token, x-token")
        context.Header("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE, PATCH, PUT")
        context.Header("Access-Control-Expose-Headers", "Content-Length, Access-Control-Allow-Origin, Access-Control-Allow-Headers, Content-Type")
        context.Header("Access-Control-Allow-Credentials", "true")

        if method == "OPTIONS" {
            context.AbortWithStatus(http.StatusNoContent)
        }
        context.Next()
    }
}
解决思路

1. 修复路由匹配问题

报错中的请求地址是http://127.0.0.1:9999/inlog/(末尾带斜杠),但你的路由定义是/inlog(无斜杠)。Gin路由严格匹配,带斜杠的请求会找不到对应POST路由,返回404,而404响应不会携带CORS头,触发错误。

解决方式二选一:

  • 修改Axios请求地址,去掉末尾斜杠,改为http://127.0.0.1:9999/inlog
  • 在Gin中添加带斜杠的路由:r.POST("/inlog/", ...),同时匹配两种请求格式

2. 简化CORS配置,排除自定义逻辑漏洞

自定义中间件可能存在逻辑冲突,推荐直接使用官方github.com/gin-contrib/cors包,先配置最简化规则验证:

import "github.com/gin-contrib/cors"

func main() {
    r := gin.Default()
    // 最简CORS配置
    r.Use(cors.New(cors.Config{
        AllowAllOrigins: true,
        AllowMethods: []string{"GET", "POST", "OPTIONS", "PUT", "DELETE"},
        AllowHeaders: []string{"*"},
    }))

    r.POST("/inlog", func(c *gin.Context) {
        c.JSON(200, gin.H{"status": "OK", "message": "pong"})
    })

    r.GET("/ping", func(c *gin.Context) {
        c.JSON(200, gin.H{"message": "pong"})
    })
    r.Run(":9999")
}

3. 确保OPTIONS请求正确处理

跨域POST会先发送OPTIONS预检请求,若中间件未正确处理则预检失败。官方cors包会自动处理OPTIONS请求,无需手动编写逻辑。

若坚持自定义中间件,需注意:

  • 处理OPTIONS请求时,必须先设置所有CORS头,再调用AbortWithStatus(http.StatusNoContent)
  • 避免在OPTIONS分支中设置冲突的头(比如Cors1中同时设置Allow-Methods为OPTIONS和多种方法)

4. 验证响应头是否生效

用curl发送OPTIONS请求,检查响应头是否包含Access-Control-Allow-Origin:

curl -X OPTIONS -H "Origin: http://127.0.0.1:8080" -i http://127.0.0.1:9999/inlog

若响应头无该字段,说明中间件未生效,检查是否在路由注册前调用了r.Use(corsMiddleware)(中间件必须在路由定义前加载)

内容的提问来源于stack exchange,提问作者Iteravse

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 06:24:55