douxuqiao6394
2018-10-09 07:29
浏览 250
已采纳

Gin-Gonic(golang)服务器上的Axios POST不起作用

I can use GET, but I cannot use POST from axios, sending data to my gin-gonic golang server. It works perfectly in Postman. When I shoot over the request with Axios, I get nothing in return.

When I go into the gin-gonic server, it shows that it returned a 500 error. Upon further inspection, I see that none of the post variables had been accessed by gin.

When I have used Postman, the server returns the array as specified. I have a feeling that it might have to do with headers, but I truly am stumped. I have encountered this problem about 6 months ago and never figured it out. Now I remember why I didn't continue with axios and nuxt :).

Here is the golang gin-gonic server route.

func initServer() {
    router := gin.Default()
    config := cors.DefaultConfig()
    config.AddAllowHeaders("*",)
    config.AllowAllOrigins = true
    config.AllowMethods = []string{"POST", "GET"}
    router.Use(cors.New(config))
    v1 := router.Group("/api/v1/stripe")
    {
        v1.POST("/pay", BuyProduct)
        v1.POST("/card", UpdateCard)
        v1.GET("/products", GetAllProducts)
        v1.GET("/products/id/:productId", GetProduct)
        v1.GET("/products/types/:typeId", GetProductType)
        v1.GET("/products/types", GetAllProductTypes)
    }

    // You can get individual args with normal indexing.
    serverAddress := "127.0.0.1:8080"
    if len(os.Args) > 1 {
        arg := os.Args[1]
        serverAddress = fmt.Sprintf("127.0.0.1:%v", arg)
    }

    router.Run(serverAddress)
}

Here is the receiver function that processes the router calls when the endpoint is hit

func BuyProduct(c *gin.Context) {

    postUserID := c.PostForm("userId")
    postProductId := c.PostForm("productId")
    token := c.PostForm("token")

    userId, err := strconv.Atoi(postUserID)
    if err != nil {
    panic(err)
    }
    productId, err := strconv.Atoi(postProductId)
    if err != nil {
        panic(err)
    }

    custy := user.InitCustomer(int64(userId), token)
    custy.GetStripeCustomerData()
    custy.SelectProduct(products.NewProduct(int64(productId)))
    custy.Purchase()

    c.JSON(200, gin.H{"status": 200,
        "product": custy.Product,
        "user": *custy.Saver.User,
        "subscriptions": *custy.Subscriptions,
        "ch": custy.Logs,
    })

    return
}

Here is my axios (nuxt) code.

async purchaseSubscription() {
    const paid = await 
    this.$axios.$post('http://localhost:8080/api/v1/stripe/pay', { data: { 
        userId: "121",
        productId: this.productId,
    }, query: {  } })
    this.paid = paid
},

Here is the error I get in the gin-gonic server in go

2018/10/09 00:12:34 [Recovery] 2018/10/09 - 00:12:34 panic recovered:
POST /api/v1/stripe/pay HTTP/1.1
Host: localhost:8080
Accept: application/json, text/plain, /
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9
Cache-Control: no-cache
Connection: keep-alive
Content-Length: 52
Content-Type: application/json;charset=UTF-8
Dnt: 1
Origin: http://localhost:3000
Pragma: no-cache
Referer: http://localhost:3000/
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36
strconv.Atoi: parsing "": invalid syntax
/usr/local/go/src/runtime/panic.go:502 (0x102aca8)
gopanic: reflectcall(nil, unsafe.Pointer(d.fn), deferArgs(d), uint32(d.siz), uint32(d.siz))
/Users/joealai/go/src/sovrin-mind-stripe/sm-stripe.go:150 (0x15f9ee5)
BuyProduct: panic(err)
[GIN] 2018/10/09 - 00:12:34 | 500 | 1.079498ms | 127.0.0.1 | POST /api/v1/stripe/pay

  • 点赞
  • 写回答
  • 关注问题
  • 收藏
  • 邀请回答

2条回答 默认 最新

  • duancaozen6066 2018-10-09 07:45
    已采纳

    I think the problem is not with gin or not gin, it's just with your call. Notice that you're accessing to the c.PostForm values but in your axios call you're not sending a form values, you're sending a json, so in your variables the value is empty. If you're using Postman I suppose you're doing well sending a PostForm, but not in your axios. My recommendation is to still sending a Post (also add a content-type: application-json header) and c.Bind the body to a struct or a map[string]interface{} and then cast to your specific types in your handler.

    点赞 打赏 评论
  • dongxie2749 2018-10-09 08:20

    There is no JSON POST Retrieval built into gin-gonic, and from what I understand, in Go's basic Web Server Package. Instead, we need to use c.GetRawData(), and then unmarshal the results into a struct! Since the c.GetRawData() includes data: { userId: 121, productId: 12, token: tok_visa }, the struct must also contain the data json field as well. I hope this helps someone else! Thanks @Carles

    type Buy struct {
        Data struct {
            User    int64 `json:"userId" binding:"required"`
            Product int64 `json:"productId" binding:"required"`
            Token   string `json:"token"`
        } `json:"data"`
    }
    
    func BuyProduct(c *gin.Context) {
    
        a := Buy{}
        b, err := c.GetRawData()
        if err != nil {
            panic(err)
        }
        json2.Unmarshal(b, &a)
        userId := a.Data.User
        productId := a.Data.Product
    
        token := a.Data.Token
    
    点赞 打赏 评论

相关推荐 更多相似问题