简体   繁体   English

将封送处理的 JSON 数据作为 URL 编码的表单数据发布

[英]Post Marshaled JSON data as URL Encoded Form Data

I'm trying to send a POST request by converting an auth structure to application/x-www-form-urlencoded data.我正在尝试通过将身份验证结构转换为application/x-www-form-urlencoded数据来发送 POST 请求。

package main

import (
    "bytes"
    "encoding/json"
    "io/ioutil"
    "log"
    "net/http"
)

type Payload struct {
    Username string `json:"username"`
    Password string `json:"password"`
    GrantType string `json:"grant_type"`
    Scope string `json:"scope"`
}

func main() {

    var endpoint string = "https://api.io/v1/oauth/token"

    jsonPay := &Payload{
        Username: "email",
        Password: "pass",
        GrantType: "password",
        Scope: "SPACE SEPARATED STRINGS",
    }

    //byteArr, err := json.Marshal(jsonPay)
    //if err != nil {
    //    log.Printf("Unable to map structure\n%v", err)
    //}

    payloadBuf := new(bytes.Buffer)
    json.NewEncoder(payloadBuf).Encode(jsonPay)

    req, err := http.NewRequest("POST", endpoint, payloadBuf)
    if err != nil {
        log.Fatal(err)
    }
    req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
    req.Header.Add("Accept", "application/json")

    resp, err := http.DefaultClient.Do(req)
    if err != nil {
        log.Fatal(err)
    }
    defer resp.Body.Close()

    body, err := ioutil.ReadAll(resp.Body)
    if err != nil {
        log.Fatal(err)
    }
    log.Printf(string(body))

}

I've tried:我试过了:

  1. Sending a JSON encoded payload buffer, which returns发送 JSON 编码的有效负载缓冲区,该缓冲区返回

    {"error":"invalid_request","error_description":"Missing grant type"}
  2. Using bytes.NewReader with the marshaled JSON object, which also returnsbytes.NewReader与封送处理的 JSON 对象一起使用,该对象也返回

    {"error":"invalid_request","error_description":"Missing grant type"}
  3. Using strings.NewReader with the JSON encoded payload buffer, which returnsstrings.NewReader与 JSON 编码的有效负载缓冲区一起使用,该缓冲区返回

    cannot use payloadBuf (variable of type *bytes.Buffer) as type string in argument to strings.NewReader

The curl request looks like: curl 请求如下所示:

curl --request POST \
  --url https://api.io/v1/oauth/token \
  --header 'Content-Type: application/x-www-form-urlencoded' \
  --data 'username=email' \
  --data 'password=pass' \
  --data 'grant_type=password' \
  --data 'scope=SPACE SEPARATED STRINGS'

and works with:并与:

package main

import (
    "io/ioutil"
    "log"
    "net/http"
    "net/url"
    "strings"
)

func main() {

    const endpoint string = "https://api.io/v1/oauth/token"

    payload := url.Values{
        "username":   {"email"},
        "password":   {"pass"},
        "grant_type": {"password"},
        "scope":      {"SPACE SEPARATED STRINGS"},
    }

    req, err := http.NewRequest("POST", endpoint, strings.NewReader(payload.Encode()))
    if err != nil {
        log.Printf("Unable to perform POST request:\n%v", err)
    }
    req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
    req.Header.Add("Accept", "application/json")

    resp, err := http.DefaultClient.Do(req)
    if err != nil {
        log.Fatal(err)
    }
    defer resp.Body.Close()

    body, err := ioutil.ReadAll(resp.Body)
    if err != nil {
        log.Fatal(err)
    }
    log.Println(string(body))
}

How do I post marshaled JSON data as application/x-www-form-urlencoded如何将编组的 JSON 数据发布为application/x-www-form-urlencoded

Implemented @RedBlue's suggestion:实施@RedBlue 的建议:

package main

import (
    "io/ioutil"
    "log"
    "net/http"
    "strings"
    "net/url"
)

type Payload struct {
    Username string `json:"username"`
    Password string `json:"password"`
    GrantType string `json:"grant_type"`
    Scope string `json:"scope"`
}

func main() {

    const endpoint string = "https://api.io/v1/oauth/token"

    formData := &Payload{
        Username: "email",
        Password: "pass",
        GrantType: "password",
        Scope: "SPACE SEPARATED STRINGS",
    }

    payload := url.Values{
        "username":   {formData.Username},
        "password":   {formData.Password},
        "grant_type": {formData.GrantType},
        "scope":      {formData.Scope},
    }

    req, err := http.NewRequest("POST", endpoint, strings.NewReader(payload.Encode()))
    if err != nil {
        log.Printf("Unable to perform POST request:\n%v", err)
    }
    req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
    req.Header.Add("Accept", "application/json")

    resp, err := http.DefaultClient.Do(req)
    if err != nil {
        log.Fatal(err)
    }
    defer resp.Body.Close()

    body, err := ioutil.ReadAll(resp.Body)
    if err != nil {
        log.Fatal(err)
    }
    log.Println(string(body))
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM