[http] `http.NewRequest (…)`를 사용하여 URL 인코딩 된 POST 요청을 만듭니다.

내 데이터를 application/x-www-form-urlencoded콘텐츠 유형 으로 보내는 API에 POST 요청을하고 싶습니다 . 요청 헤더를 관리해야하기 때문에이 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")
    r.Header.Add("Content-Length", strconv.Itoa(len(data.Encode())))

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

resp.Status입니다 200 OK이런 식으로.


답변