forms - 没有获取使用 go 发送的表单数据

标签 forms api http go

我是 Golang 新手,有 Python 背景,在管理表单请求时遇到一些问题。

我正在尝试使用 Go 以表单格式发送数据,以模仿此curl 调用:

curl -X POST -k  --cacert mycert --key mykey --cert cert "https://api/v1/house?action=paint&room=hall" -F "houses=street123"

这是我在 API 服务器(在 Flask 上运行)中看到的内容,它通过curl 检查请求中的 header 和表单信息进行调用。

标题

Host: localhost
Connection: close
Content-Length: 152
User-Agent: curl/7.29.0
Accept: */*
Content-Type: multipart/form-data; boundary=----------------------------991133af3afb

表格

ImmutableMultiDict([('houses', 'street123')])

当我使用 GO 代码执行此操作时,我得到以下信息:

标题

Host: localhost
Connection: close
Content-Length: 18
User-Agent: Go-http-client/1.1
Accept-Encoding: */*
Content-Type: multipart/form-data

表格

ImmutableMultiDict([])

我在做什么:

1-我正在 Generate_client 中生成一个客户端,用于通过相互 tls 进行身份验证

2- 我使用 map[string][]string 作为负载来调用 API,并在调用之前打印它以确保它已正确构造。

  1. 我在调用函数时返回正文并打印它。

这是我的结果:

Doing Form call
Params after maping:map[houses:[street123]]
FULL-URL:https://api/v1/house?action=paint&room=hall
Params encoded:&{houses=street123 0 -1}

这是我的代码

func Generate_client() *http.Client {
    caCert, err := ioutil.ReadFile(cacert)
    checkForErrors(err)
    caCertPool := x509.NewCertPool()
    caCertPool.AppendCertsFromPEM(caCert)
    // Create key pair for certificate
    cert, err := tls.LoadX509KeyPair(cert, key)
    checkForErrors(err)
    client := &http.Client{
        Transport: &http.Transport{
            TLSClientConfig: &tls.Config{
                RootCAs: caCertPool,
                Certificates: []tls.Certificate{cert},
            },
        },
    }
    return client
}


func CallFormUrl(endpoint string, method string, dataPayload []string) string {
    fmt.Println("Doing Form call")
    FormMap := ConvertPayloadToMap(dataPayload)
    params := url.Values{}
    for key, value:= range FormMap{
        params.Add(key,value)
    }
    fmt.Println("Params after maping:"+params)

    client := Generate_client()
    fullUrl := controllerUrl+endpoint
    fmt.Println("FULL-URL:"+fullUrl)
    var ContentType string = "multipart/form-data"
    var err error
    var req *http.Request
    fmt.Println("Params encoded:"+strings.NewReader(params.Encode()))
    switch method {
    case "POST":
        req, err = http.NewRequest(http.MethodPost, fullUrl, strings.NewReader(params.Encode()))
    case "PUT":
        req, err = http.NewRequest(http.MethodPut, fullUrl, strings.NewReader(params.Encode()))
    case "GET":
        req, err = http.NewRequest(http.MethodGet, fullUrl, strings.NewReader(params.Encode()))
    case "DELETE":
        req, err = http.NewRequest(http.MethodDelete, fullUrl, strings.NewReader(params.Encode()))
    }
    req.Header.Set("Content-type", ContentType)
    checkForErrors(err)
    resp, err:= client.Do(req)
    checkForErrors(err)
    defer resp.Body.Close()
    body, err := ioutil.ReadAll(resp.Body)
    return string(body)
}

为什么表单数据没有发送出去?

最佳答案

构建多部分请求比构建普通的 urlencoded 表单更为冗长,因此如果您需要在很多地方使用多部分,您可能希望将其抽象为一个函数,以便让您的生活更轻松。

这是一个例子:

params := url.Values{"houses": {"street123"}}
buf := bytes.Buffer{}
w := multipart.NewWriter(&buf)
ct := w.FormDataContentType()

h := make(textproto.MIMEHeader)
h.Set("Content-Type", "application/x-www-form-urlencoded")
if pw, err := w.CreatePart(h); err != nil {
    panic(err)
} else if _, err := pw.Write([]byte(params.Encode())); err != nil {
    panic(err)
} else if err := w.Close(); err != nil {
    panic(err)
}

r, err := http.NewRequest("POST", "https://example.com", &buf)
if err != nil {
    panic(err)
}
r.Header.Set("Content-Type", ct)

re, err := client.Do(r)
// ...

https://play.golang.org/p/nzfUjBBh7_w

关于forms - 没有获取使用 go 发送的表单数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62554131/

相关文章:

jquery - 如何跨浏览器检测 jQuery 中具有 'required' 属性的输入字段?

php - 如何将数组存储在数据库列中

forms - jQuery UI 选项卡和 Cookie 选项出现问题

javascript - Facebook API 站点 URL

http - 使用 SSL 连接时可以看到哪些 http header ?

.htaccess - 如何将 http url 重定向到 https url?

php - PHP 不区分大小写吗?

python - 响应上传确认,然后在 Sanic 中处理文件

json - 当我尝试访问JSON数据元素时出现Flutter:TypeError

http - 有哪些好的免费 Http 调试工具