使用`http.NewRequest(…)`做一个URL编码的POST请求

我想要一个POST请求发送我的数据作为application/x-www-form-urlencoded内容types的API。 由于我需要pipe理请求头,我使用http.NewRequest(method, urlStr string, body io.Reader)方法来创build一个请求。 对于这个POST请求,我将我的数据查询附加到URL中,并将主体留空,如下所示:

 package main import ( "bytes" "fmt" "net/http" "net/url" "strconv" ) func main() { apiUrl := "https://api.com" resource := "/user/" data := url.Values{} data.Set("name", "foo") data.Add("surname", "bar") u, _ := url.ParseRequestURI(apiUrl) u.Path = resource u.RawQuery = data.Encode() urlStr := fmt.Sprintf("%v", u) // "https://api.com/user/?name=foo&surname=bar" client := &http.Client{} r, _ := http.NewRequest("POST", urlStr, nil) r.Header.Add("Authorization", "auth_token=\"XXXXXXX\"") r.Header.Add("Content-Type", "application/x-www-form-urlencoded") r.Header.Add("Content-Length", strconv.Itoa(len(data.Encode()))) resp, _ := client.Do(r) fmt.Println(resp.Status) } 

正如我的回应,我总是得到一个400 BAD REQUEST 。 我相信这个问题依赖于我的请求,API不知道我发布了哪个有效载荷。 我知道的方法,如Request.ParseForm ,但不知道如何在这种情况下使用它。 也许我错过了一些进一步的头,也许有更好的方式发送有效载荷作为application/jsontypes使用body参数?

作为实现io.Reader接口的types,必须在http.NewRequest(method, urlStr string, body io.Reader)方法的body参数上提供URL编码的有效内容。

根据示例代码:

 package main import ( "fmt" "net/http" "net/url" "strconv" "strings" ) func main() { apiUrl := "https://api.com" resource := "/user/" data := url.Values{} data.Set("name", "foo") data.Add("surname", "bar") u, _ := url.ParseRequestURI(apiUrl) u.Path = resource urlStr := u.String() // "https://api.com/user/" client := &http.Client{} r, _ := http.NewRequest("POST", urlStr, strings.NewReader(data.Encode()) // <-- URL-encoded payload r.Header.Add("Authorization", "auth_token=\"XXXXXXX\"") r.Header.Add("Content-Type", "application/x-www-form-urlencoded") r.Header.Add("Content-Length", strconv.Itoa(len(data.Encode()))) resp, _ := client.Do(r) fmt.Println(resp.Status) } 

resp.Status200 OK这样的。