使用Go的HTTP post方法来模拟curl命令中的-d参数。

huangapple go评论83阅读模式
英文:

Getting Go's HTTP post to emulate curl -d

问题

我正在尝试通过Go将内容发布到一个nginx服务器。我已经验证过,我可以通过curl正确地发布这个内容,具体使用以下命令:

$ curl http://example.com/myendpoint -d "Some Text"

我能够看到这个POST请求,并且正确地处理它。然而,当我尝试使用Go进行POST请求时,服务器会拒绝它。在nginx的访问日志中,我看到了以下两行:

127.0.0.1 - - [30/Jan/2014:05:57:34 +0000] "POST /myendpoint HTTP/1.1" 400 0 "-" "Go 1.1 package http"
127.0.0.1 - - [30/Jan/2014:05:57:39 +0000] "Some Text" 400 172 "-" "-"

我尝试的代码如下:

r, err := http.Post(uri, "application/x-www-form-urlencoded", bytes.NewReader(data))
if err != nil {
  log.Printf("HTTP NOTIFICATION ERROR: %s\n", err)
  return
}
r.Body.Close()

我做错了什么吗?谢谢!

英文:

I am attempting to post content to an nginx server through Go. I have verified that I am able to correctly POST this content through curl, specifically using this command:

$ curl http://example.com/myendpoint -d "Some Text"

I am able to see this POST, and process it correctly. However, when I try to perform a POST with Go, it is rejected by the server. In the nginx access logs, I see these two lines:

127.0.0.1 - - [30/Jan/2014:05:57:34 +0000] "POST /myendpoint HTTP/1.1" 400 0 "-" "Go 1.1 package http"
127.0.0.1 - - [30/Jan/2014:05:57:39 +0000] "Some Text" 400 172 "-" "-"

The code that I have tried is below:

<!-- language: go -->

r, err := http.Post(uri, &quot;application/x-www-form-urlencoded&quot;, bytes.NewReader(data))
if err != nil {
  log.Printf(&quot;HTTP NOTIFICATION ERROR: %s\n&quot;, err)
  return
}
r.Body.Close()

Is there something that I am doing wrong? Thanks!

答案1

得分: 3

我无法看到你提供的代码片段中的任何特定问题,但是你可能没有按照application/x-www-form-urlencoded规范要求对数据进行编码。

尝试使用PostForm,它会代表你执行这个操作:

import (
    "net/url"
)

// ...

r, err := http.PostForm(uri, url.Values{"key": {"Value"}, "id": {"123"}})
英文:

I can't see any particular issue with the code snippets you provided, but you may not be encoding the data as required by application/x-www-form-urlencoded's specification.

Try using PostForm instead, which will perform this on your behalf:

import (
    &quot;net/url&quot;
)

// ...

r, err := http.PostForm(uri, url.Values{&quot;key&quot;: {&quot;Value&quot;}, &quot;id&quot;: {&quot;123&quot;}})

答案2

得分: -1

如果你更方便将你的帖子数据转换为[]byte而不是url.Values,你可以使用http.Client。下面的代码展示了如何使用Client来处理一个新的http请求。

var client http.Client
req, err := http.NewRequest("POST", myURL, data) // data的类型是[]byte

if err != nil {
    // todo: 做一些处理
}
req.Header.Add("Content-Type", "application/x-www-form-urlencoded")

resp, err := client.Do(req)
if err != nil {
    // todo: 做一些处理
}
defer resp.Body.Close()

// 处理你的响应。

希望对你有帮助!

英文:

If it is more convenient for you to convert your post data to []byte, vs url.Values, you can use http.Client. The code below shows how you can use the Client to process a new http request.

var client http.Client
req, err := http.NewRequest(&quot;POST&quot;, myURL, data) // data is of type []byte
 
if err != nil {		
    // todo: do something
}
req.Header.Add(&quot;Content-Type&quot;, &quot;application/x-www-form-urlencoded&quot;)

resp, err := client.Do(req)
if err != nil {
               // todo: do something
}
defer resp.Body.Close()

    // process your response.

huangapple
  • 本文由 发表于 2014年1月31日 11:06:21
  • 转载请务必保留本文链接:https://go.coder-hub.com/21471725.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定