我想向API发出POST请求,将我的数据作为application/x-www-form-urlencoded内容类型发送.由于我需要管理请求头,所以我使用http.NewRequest(method, urlStr string, body io.Reader)方法来创建请求.对于此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这样的方法,但是不太确定如何在这个上下文中使用它.也许我遗漏了更多的头,也许有更好的方式使用body参数将有效负载作为application/json类型发送?

推荐答案

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

根据示例代码:

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.Set("surname", "bar")

    u, _ := url.ParseRequestURI(apiUrl)
    u.Path = resource
    urlStr := u.String() // "https://api.com/user/"

    client := &http.Client{}
    r, _ := http.NewRequest(http.MethodPost, 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")

    resp, _ := client.Do(r)
    fmt.Println(resp.Status)
}

这边resp.Status等于200 OK.

Go相关问答推荐

"k8s.io/apimachinery/pkg/runtime.对象(缺少方法DeepCopyBody)

杜松子wine -戈尼克背景在 children 围棋例行公事中被取消

从Kafka到Clickhouse的实时消费数据

运行add. inf,这样我们就可以在app.conf中使用. inf参数了?

golang 的通用 map 功能

使用一元或服务器流将切片从GRPC服务器返回到客户端

go mod tidy会自动升级go.mod中的go版本吗?

go aws-lambda 与 terraform 中的 exec 格式错误

Go 中带有回调的 MiniDumpWriteDump

这是go语言gin提供的关于TypeEngine和RouterGroup的问题

在VSCode中如何使用特定的文件名提供编译命令

我无法使用反向代理更改主机标头

Go Template if 条件

fmt.Printf() 标志 '0' 不会被字符串忽略

在我的情况下,如何以正确的方式测试方法?

如何在gin中获取参数值数组

为什么 x/net/html Token().Attr 上的 len 在此处为空切片返回非零值?

如何在 docker 文件中安装 golang 包?

为什么在 goroutine 中声明时,benbjohnson/clock 模拟计时器不执行?

Gin中测试模式有什么用