在go中发布带有数据的请求

时间:2015-02-04 09:57:57

标签: go

我正在尝试访问这样的API:

package main

import (
    "bytes"
    "fmt"
    "io/ioutil"
    "net/http"
    "net/url"
)

func main() {
    apiUrl := "https://example.com/api/"
    data := url.Values{}
    data.Set("api_token", "MY_KEY")
    data.Add("action", "list_projects")
    req, _ := http.NewRequest("POST", apiUrl, bytes.NewBufferString(data.Encode()))
    client := &http.Client{}
    resp, err := client.Do(req)
    defer resp.Body.Close()
    if err == nil {
        body, _ := ioutil.ReadAll(resp.Body)
        fmt.Println(resp.Status)
        fmt.Println(string(body))
    }
}

但API的响应告诉我POST请求中没有数据。

如果我使用curl这样做,它可以工作:

$ curl -X POST "https://example.com/api/" -d "api_token=MY_KEY" -d "action=list_projects"

1 个答案:

答案 0 :(得分:2)

您可能希望使用此形式的请求

resp, err := http.PostForm("http://example.com/form", 
                            url.Values{"key": {"Value"}, "id": {"123"}})

或使用正确的mime类型:

req.Header.Set("Content-Type", "application/x-www-form-urlencoded")

并编码数据

strings.NewReader(data.Encode())

如果你测试err!= nil并且必要时返回它会更好。此代码可能无效,导致请求失败。

defer resp.Body.Close()

改为使用这种模式:

client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
    fmt.Println(err)
    return
}
defer resp.Body.Close()
body, _ := ioutil.ReadAll(resp.Body)
fmt.Println(resp.Status)
fmt.Println(string(body))

因此,您可以在控制台中看到请求是否失败