Создайте запрос POST в кодировке URL с помощью `http.NewRequest (…)`

Я хочу сделать POST-запрос к API, отправив мои данные в виде типа контента 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 параметр?

72 голоса | спросил Fernando Á. 8 +04002013-10-08T20:38:54+04:00312013bEurope/MoscowTue, 08 Oct 2013 20:38:54 +0400 2013, 20:38:54

1 ответ


0

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("POST", 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 таким образом .

ответил Fernando Á. 8 +04002013-10-08T21:05:03+04:00312013bEurope/MoscowTue, 08 Oct 2013 21:05:03 +0400 2013, 21:05:03

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132