Je souhaite envoyer une requête POST à une API qui envoie mes données en tant que application/x-www-form-urlencoded
type de contenu. Étant donné que je dois gérer les en-têtes de demande, j'utilise la http.NewRequest(method, urlStr string, body io.Reader)
méthode pour créer une demande. Pour cette demande POST, j'ajoute ma requête de données à l'URL et laisse le corps vide, quelque chose comme ceci:
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)
}
En réponse, j'obtiens toujours un 400 BAD REQUEST
. Je pense que le problème repose sur ma demande et que l'API ne comprend pas la charge utile que je publie. Je connais des méthodes comme Request.ParseForm
, je ne sais pas vraiment comment l'utiliser dans ce contexte. Est-ce que je manque peut-être un autre en-tête, peut-être existe-t-il un meilleur moyen d'envoyer la charge utile en tant que application/json
type à l'aide du body
paramètre?
b
donnévar b bytes.Buffer
Content-Lenght
tête, commehttp.NewRequest
c'est déjà le cas.strings.NewReader(data.Encode())
(plus efficace) au lieu debytes.NewBufferString(data.Encode())
. À func NewReader (s string) * Reader , il dit "NewReader renvoie une nouvelle lecture de Reader à partir de s. Il est similaire à bytes.NewBufferString mais plus efficace et en lecture seule."data.Set
doit être utilisé pour les deuxname
etsurname
, au lieu dedata.Add
. Il définit la valeur de la clé, au lieu d'ajouter une autre valeur à la même clé, comme ledata.Add
fait.Add
fonctionne aussi, mais ne permet pasappend(v[key], value)
de vider la tranche.