在Go语言中如何发送POST请求?

115

我正在尝试进行POST请求,但无法完成。另一端没有收到任何内容。

这应该是正常的工作方式吗?我知道有PostForm函数,但我认为不能使用它,因为它无法通过httputil进行测试,对吗?

hc := http.Client{}
req, err := http.NewRequest("POST", APIURL, nil)

form := url.Values{}
form.Add("ln", c.ln)
form.Add("ip", c.ip)
form.Add("ua", c.ua)
req.PostForm = form
req.Header.Add("Content-Type", "application/x-www-form-urlencoded")

glog.Info("form was %v", form)
resp, err := hc.Do(req)

2
可能是重复问题:https://dev59.com/ZmIk5IYBdhLWcg3wdd_Y - nvcnvn
你正在使用 httputil 进行什么测试? - JimB
HTTP 处理程序。我认为它是一种端到端测试。 - hey
2个回答

173

你的想法大体上是正确的,只是表单的发送方式有误。表单应该放在请求主体中。

req, err := http.NewRequest("POST", url, strings.NewReader(form.Encode()))

19
没问题,刚才我看了一下那个东西,似乎你需要阅读源代码而不仅仅是Godoc来理解它应该如何工作。 - hey
12
提交前不要忘记添加Content-Type: req.Header.Add("Content-Type", "application/x-www-form-urlencoded") - colm.anseo

69

我知道这已经过时了,但是这个答案出现在搜索结果中。对于下一个人 - 所提出的和被接受的答案是有效的,但最初在问题中提交的代码比它需要的低级别。没人有时间进行那样的操作。

//one-line post request/response...
response, err := http.PostForm(APIURL, url.Values{
    "ln": {c.ln},
    "ip": {c.ip},
    "ua": {c.ua}})

//okay, moving on...
if err != nil {
  //handle postform error
}

defer response.Body.Close()
body, err := ioutil.ReadAll(response.Body)

if err != nil {
  //handle read response error
}

fmt.Printf("%s\n", string(body))

https://golang.org/pkg/net/http/#pkg-overview


1
你说OP的代码比必要的还长,但是你的代码没有处理设置头部req.Header.Add("Content-Type", "application/x-www-form-urlencoded") - jsnfwlr
15
根据https://golang.org/pkg/net/http/#PostForm,`PostForm`会自动将`Content-Type`标头设置为`application/x-www-form-urlencoded`。 - Chuck Wooters
1
如果您想添加其他标头,例如基本授权,是否有方法? - huggie
1
@huggie 不是的,源代码文档 https://golang.org/src/net/http/client.go?s=28199:28281#L848 表明:“要设置其他标头,请使用 NewRequest 和 Client.Do。” - CenterOrbit
呵呵,我就知道这个太简单了——我希望有一种方法可以使用http.PostForm来指定头部信息。嘟囔,咕哝... - undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接