Imgur API:POST 在 GO 中发表评论

Imgur API: POST comment in GO

我正在尝试 POST 通过 Imgur API 向 imgur 发表评论。但我无法使有效载荷正确。我已经浏览了 Imgur 的页面,他们表明它应该像我在 strings.NewReader 中那样编码。图片 ID 为 nP0uKKO

func HandleComment(w http.ResponseWriter, r *http.Request){
parts := strings.Split(r.URL.Path, "/")

switch r.Method {

case "POST":
    // URL for POSTing comment
    url := "https://api.imgur.com/3/comment"

    // Authorization key
    token := "Bearer " + os.Getenv("TOKEN")

    // Payload
    payload := strings.NewReader("------WebKitFormBoundary7MA4YWxkTrZu0gW\r\nContent-Disposition: form-data; name=\"image_id\"\r\n\r\nnP0uKKO\r\n------WebKitFormBoundary7MA4YWxkTrZu0gW\r\nContent-Disposition: form-data; name=\"comment\"\r\n\r\nI'm a giraffe!\r\n------WebKitFormBoundary7MA4YWxkTrZu0gW--")

    // Get body and http status code
    body, status := DoStuff(parts[2], url, payload, token)

    // If status is not OK
    if status != 200 {
        http.Error(w, "Could not post comment", status)
    } else {
        fmt.Fprintln(w, string(body))
    }

DoStuff() 做这个

func DoStuff(method string, url string, body io.Reader, key string) ([]byte, int) {

    // New request
    req, err := http.NewRequest(method, url, body)
    if err != nil {
        fmt.Println(err)
    }

    // Add header with 'key' authorization
    req.Header.Add("authorization", key)

    res, err := http.DefaultClient.Do(req)
    if err != nil {
        fmt.Println(err)
    }

    defer res.Body.Close()

    imgBody, err := ioutil.ReadAll(res.Body)
    if err != nil {
        fmt.Println(err)
    }

    return imgBody, res.StatusCode
} 

我刚收到这个错误

 {
   data: {
           error: "The parameter, image_id, is required.",
           request: "/3/comment",
           method: "POST"
   },
   success: false,
   status: 400
 }

缺少的是 Content-Type header。您可以这样修改您的代码:

在您的处理程序中 HandleComment 您可以定义要传递给请求的 headers

case "POST":
    // URL for POSTing comment
    url := "https://api.imgur.com/3/comment"

    // Authorization key
    token := "Bearer " + os.Getenv("TOKEN")

    // Payload
    payload := strings.NewReader("------WebKitFormBoundary7MA4YWxkTrZu0gW\r\nContent-Disposition: form-data; name=\"image_id\"\r\n\r\nnP0uKKO\r\n------WebKitFormBoundary7MA4YWxkTrZu0gW\r\nContent-Disposition: form-data; name=\"comment\"\r\n\r\nI'm a giraffe!\r\n------WebKitFormBoundary7MA4YWxkTrZu0gW--")
    // Headers
    headers := map[string]string{
        "Authorization": token,
        "Content-Type":  "multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW",
    }

    // Get body and http status code
    body, status := DoStuff(parts[2], url, payload, headers)

    // If status is not OK
    if status != 200 {
        http.Error(w, "Could not post comment", status)
    } else {
        fmt.Fprintln(w, string(body))
    }

更新 DoStuff 以读取并传递 headers

func DoStuff(method string, url string, body io.Reader, headers map[string]string) ([]byte, int) {

    // New request
    req, err := http.NewRequest(method, url, body)
    if err != nil {
      fmt.Println(err)
    }

    // Add headers
    for k, v := range headers {
      req.Header.Add(k, v)
    }

    res, err := http.DefaultClient.Do(req)
    if err != nil {
      fmt.Println(err)
    }

    defer res.Body.Close()

    imgBody, err := ioutil.ReadAll(res.Body)
    if err != nil {
      fmt.Println(err)
    }

    return imgBody, res.StatusCode
}

我建议您可以使用 json 内容类型,而不是使用 multipart/form-data;。它更易于管理且更具可读性

// Payload
payload := strings.NewReader("{\"image_id\": \"nP0uKKO\", \"comment\": \"I'm a giraffe!\"}")
// Headers
headers := map[string]string{
    "Authorization": token,
    "Content-Type":  "application/json",
}