使用Go语言进行带有数据的POST请求。

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

Post request with data in 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"
英文:

I'm trying to access an API like this:

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))
	}
}

But the response from an API tells me there was no data in POST request.

If I do it like this with curl, it works:

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

答案1

得分: 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))

这样你就可以在控制台上看到请求是否失败了。

英文:

You may want to use this form of request

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

or use the right mime type :

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

and encode data

strings.NewReader(data.Encode())

It's better if you test err != nil and return if necessary. This code may not work cause the request failed.

defer resp.Body.Close()

instead use this pattern:

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))

So you can see in the console if the request failed or not

huangapple
  • 本文由 发表于 2015年2月4日 17:57:57
  • 转载请务必保留本文链接:https://go.coder-hub.com/28318415.html
匿名

发表评论

匿名网友

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

确定