为什么在使用CORS时,Go服务器会响应307状态码?

huangapple go评论75阅读模式
英文:

Why go server responds with 307 when CORS used

问题

我有一个非常简单的应用程序,其中包含CORS中间件,看起来工作正常,并且预检请求按预期工作。但由于某种原因,服务器在实际请求上响应307。在浏览器中重现,从Postman中正常工作。

func main() {
    router := gin.Default()
    router.Use(CORSMiddleware())

    accountsGroup := router.Group("/accounts")
    accountsGroup.POST("/", postAccount)
    router.Run("localhost:8080")
}

func CORSMiddleware() gin.HandlerFunc {
    return func(c *gin.Context) {
        c.Header("Access-Control-Allow-Origin", "*")
        c.Header("Access-Control-Allow-Credentials", "true")
        c.Header("Access-Control-Allow-Headers", "Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, Authorization, accept, origin, Cache-Control, X-Requested-With")
        c.Header("Access-Control-Allow-Methods", "POST,HEAD,PATCH, OPTIONS, GET, PUT")

        if c.Request.Method == "OPTIONS" {
            c.AbortWithStatus(204)
            return
        }

        c.Next()
    }
}

func postAccount(c *gin.Context) {
    response := gin.H{"id": 1}
    c.IndentedJSON(http.StatusCreated, response)
}

预检响应:

为什么在使用CORS时,Go服务器会响应307状态码?

实际请求:

为什么在使用CORS时,Go服务器会响应307状态码?

服务器日志:

[GIN-debug] Listening and serving HTTP on localhost:8080
[GIN] 2022/04/17 - 16:50:45 | 204 | 0s | 127.0.0.1 | OPTIONS "/accounts"
[GIN-debug] redirecting request 307: /accounts/ --> /accounts/
[GIN] 2022/04/17 - 16:52:55 | 204 | 0s | 127.0.0.1 | OPTIONS "/accounts"
[GIN-debug] redirecting request 307: /accounts/ --> /accounts/
英文:

I have a very simple app with CORS middleware that seem to work correctly and preflight request works as expected. But for some reason server responds with 307 on actual request. Reproduces in browser, from postman works correclty.

func main() {
	router := gin.Default()
	router.Use(CORSMiddleware())

	accountsGroup := router.Group("/accounts")
	accountsGroup.POST("/", postAccount)
	router.Run("localhost:8080")
}

func CORSMiddleware() gin.HandlerFunc {
	return func(c *gin.Context) {
	c.Header("Access-Control-Allow-Origin", "*")
	c.Header("Access-Control-Allow-Credentials", "true")
	c.Header("Access-Control-Allow-Headers", "Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, Authorization, accept, origin, Cache-Control, X-Requested-With")
	c.Header("Access-Control-Allow-Methods", "POST,HEAD,PATCH, OPTIONS, GET, PUT")

	if c.Request.Method == "OPTIONS" {
		c.AbortWithStatus(204)
		return
	}

	c.Next()
}


func postAccount(c *gin.Context) {
	response := gin.H{"id": 1}
	c.IndentedJSON(http.StatusCreated, response)
}

preflight response

为什么在使用CORS时,Go服务器会响应307状态码?

actual request

为什么在使用CORS时,Go服务器会响应307状态码?

server logs

[GIN-debug] Listening and serving HTTP on localhost:8080
[GIN] 2022/04/17 - 16:50:45 | 204 |            0s |       127.0.0.1 | OPTIONS  "/accounts"
[GIN-debug] redirecting request 307: /accounts/ --> /accounts/
[GIN] 2022/04/17 - 16:52:55 | 204 |            0s |       127.0.0.1 | OPTIONS  "/accounts"
[GIN-debug] redirecting request 307: /accounts/ --> /accounts/

答案1

得分: 5

你已经在/accounts/下注册了处理程序,但你正在向/accounts发出请求。这与默认设置为trueRedirectTrailingSlash选项一起使用,会导致重定向。

> 如果当前路由无法匹配,但路径中带有(不带有)尾部斜杠的处理程序存在,启用自动重定向。
> 例如,如果请求的是/foo/,但只有/foo的路由存在,
> 客户端将被重定向到/foo,对于GET请求,使用301状态码,对于其他所有请求方法,使用307状态码。

英文:

You've registered the handler under /accounts/ but you're making the request to /accounts. That coupled with the RedirectTrailingSlash setting which is by default set to true is what causes the redirect.

> Enables automatic redirection if the current route can't be matched
> but a handler for the path with (without) the trailing slash exists.
> For example if /foo/ is requested but a route only exists for /foo,
> the client is redirected to /foo with http status code 301 for GET
> requests and 307 for all other request methods.

huangapple
  • 本文由 发表于 2022年4月17日 21:56:05
  • 转载请务必保留本文链接:https://go.coder-hub.com/71902474.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定