【问题标题】:Can't change POST request to GET request using Gin/GoLang无法使用 Gin/GoLang 将 POST 请求更改为 GET 请求
【发布时间】:2023-01-11 23:16:46
【问题描述】:

ANS: 使用http.StatusSeeOther而不是http.StatusTemporaryRedirect,问题将在不改变原始请求方法的情况下得到解决。


我似乎无法在 Gin Framework 中使用 GET 方法更改 POST 方法。当我收到请求时,我想检查它的凭据,如果有效,则重定向到另一个具有 GET 端点的页面。每当我使用 c.Request.Method="GET" 时,它似乎只更改当前端点的请求,但重定向的请求仍然具有原始方法,即 POST 方法。

代码:

auth.GET("/sign-in", func(c *gin.Context) {
    c.File("../../html/index.html")
})

auth.POST("/sign-in", func(c *gin.Context) {
    c.Request.Method = "GET"
    c.Redirect(http.StatusTemporaryRedirect, "/profile/:pid")
})

Code 307请求原本是POST请求,端点自己改成了GET。

做c.Request.Method="GET"没有帮助。也找不到答案。知道如何改变这种行为吗?创建新请求是唯一的解决方案吗?

【问题讨论】:

    标签: go


    【解决方案1】:

    307 状态码documentation 说:

    重新使用原始请求的方法和主体来执行重定向的请求。在您希望使用的方法更改为 GET 的情况下,请改用 303 See Other。

    所以如果把http.StatusTemporaryRedirect改成http.StatusSeeOther,就可以不用改变原来的请求方式。

    【讨论】:

    • 辛苦了,谢谢!将把它作为答案放在问题中,也已标记。
    【解决方案2】:

    Go 按程序读取端点,因此如果它遇到 GET 请求,它不会为同一端点搜索另一个 GET 请求。最“最高”的获胜。 AFAIK,我在这里可能是错的。但 ...

    如果您将逻辑更改为以下内容怎么办?

    auth.POST("/sign-in", func(c *gin.Context) {
        c.Request.Method = "GET"
    
        // Serve the index -page
    
        // Implement the credential check logic here
    
        // Perform validation
    
        ...
    
        isValidUser, _ := checkCredentials(user.Username, user.Password)
    
        if isValidUser {
          c.Redirect(http.StatusTemporaryRedirect, "/profile/:pid")    
        }
    
        ...
    })

    按照这个逻辑,从这里继续——同时完全放弃第一个 GET 请求。

    注意:这不是有效的代码,只是您可以如何继续的想法。

    【讨论】:

    • 你能详细说明一下吗?将 c.Request.Method 放在首位到底是什么目的?比如,在重定向之前给它时间执行?如果是这样,我试过sleep“暂停”设置和重定向之间的执行但没有奏效。如果是别的,请告诉我
    • 它也击中了重定向,没有问题,但重定向后的一种方法是 POST 而不是 GET。我没有 /profile/:pid 的 GET 端点,结果是 404
    【解决方案3】:

    您是正确的,在 POST 端点中设置 c.Request.Method = "GET" 只会更改该端点的方法,并且在重定向中发送的请求的方法仍然是 POST。

    实现所需行为的正确方法是使用 c.Request.Method 来设置方法,而不是使用特定于当前请求的 Redirect,您应该使用 c.HTML 重定向,这会发出新请求并呈现新端点您想使用您设置的正确方法访问。

    您提到的 http.StatusSeeOther 状态代码也是在这种情况下使用的正确代码,因为它表示资源已被临时移动,客户端应使用 Location 标头字段中提供的新 URI 来访问资源。

    所以你的代码可能是这样的:

    auth.POST("/sign-in", func(c *gin.Context) {
        c.Request.Method = "GET"
        c.HTML(http.StatusSeeOther, "profile/:pid", nil)
    })
    

    通过这种方式,您将重定向到新位置,但会使用您想要的方法进行新请求。

    【讨论】:

      猜你喜欢
      • 2018-01-10
      • 2021-11-01
      • 2021-01-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-01-13
      • 2017-01-31
      • 2020-07-14
      相关资源
      最近更新 更多