1. ホーム
  2. http

[解決済み] http.NewRequest(...)`を使用して、URLエンコードされたPOSTリクエストを作成する。

2022-09-26 05:16:26

質問

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 のようなメソッドを知っていますが、このコンテキストでそれを使用する方法についてはよくわかりません。たぶん、私はさらなるヘッダを見逃しているのでしょう、たぶん、ペイロードを application/json 型として送信するもっと良い方法があるのかもしれません。 body パラメータを使うのですか?

どのように解決するのですか?

URL エンコードされたペイロードを body パラメータで指定する必要があります。 http.NewRequest(method, urlStr string, body io.Reader) メソッドを実装した型として 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.Status200 OK のようになります。