dtsps2098
dtsps2098
2018-10-30 00:49

如何从此请求获取POST值?

  • post
已采纳

I have the following code:

package main

import (
    "bytes"
    "fmt"
    "net/http"
)

func main() {

    var jsonStr = []byte(`{"title":"Buy cheese and bread for breakfast."}`)
    req, err := http.NewRequest("POST", "/", bytes.NewBuffer(jsonStr))
    if err != nil {
        panic(err)
    }
    req.Header.Set("X-Custom-Header", "myvalue")
    req.Header.Set("Content-Type", "application/json")

    req.ParseForm()
    fmt.Printf("%v:%v", "title", req.Form.Get("title"))
}

I am unable to extract the "title" param and not sure why.

  • 点赞
  • 写回答
  • 关注问题
  • 收藏
  • 复制链接分享
  • 邀请回答

3条回答

  • doushang2571 doushang2571 3年前

    As noted in the GoDoc for the http.Request.ParseForm method, the type of the body must be application/x-www-form-urlencoded, not JSON like your current example:

    For other HTTP methods, or when the Content-Type is not application/x-www-form-urlencoded, the request Body is not read, and r.PostForm is initialized to a non-nil, empty value.

    Here is an updated example of your code using a form body, which gives the intended result: https://play.golang.org/p/Zrw05T2Zb5Z

    If you want to extract values from a JSON body, that can be done using a method such as json.Unmarshal, however a JSON body doesn't represent a form.

    点赞 评论 复制链接分享
  • dongzhuan1185 dongzhuan1185 3年前

    The 3rd argument of http.NewRequest is the http payload.

    In your case, payload type is application/json. It's need to be treated as json, only then you'll be able to get certain value from the it. In this case, we just cannot use the same technique like on getting value from query string or form data.

    So just unmarshal the jsonStr data into map or struct.

    res := make(map[string]interface{})
    err := json.Unmarshal(jsonStr, &res)
    if err != nil {
        panic(err)
    }
    fmt.Printf("%#v 
    ", res["title"])
    

    To be honest I'm quite confused with your question, why you need to get the payload from http client request.

    If what you want is actually how to get the payload from the web server end, you can get it by decoding the request body. Example:

    http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
        payload := make(map[string]interface{})
        err := json.NewDecoder(r.Body).Decode(&payload)
        if err != nil {
            http.Error(w, err.Error(), http.StatusInternalServerError)
            return
        }
    
        title := payload["title"].(string)
        w.Write([]byte(title))
    })
    

    Curl example (based on your code):

    curl -d '{"title":"Buy cheese and bread for breakfast."}' \
         -H "Content-Type: application/json" \
         -X POST http://localhost:9000
    

    Output:

    Buy cheese and bread for breakfast.
    
    点赞 评论 复制链接分享
  • dtvpl739577 dtvpl739577 3年前

    Because your request isn't a form. It doesn't have any GET parameters, and it isn't form-encoded data.

    For other HTTP methods, or when the Content-Type is not application/x-www-form-urlencoded, the request Body is not read, and r.PostForm is initialized to a non-nil, empty value.

    [ https://golang.org/pkg/net/http/#Request.ParseForm ]

    You're free to parse the body of the request as application/json, but that isn't the same as form data.

    点赞 评论 复制链接分享

为你推荐