在我的Go应用程序中,我使用一个Web API,该API接受POST请求并在成功后返回令牌。

网址如下:" https://accounts.zoho.com/apiauthtoken/nb/create?SCOPE=xxxx&EMAIL_ID=xxxx&PASSWORD=xxxx"

如果我使用Postman或任何其他工具发送此邮件,则会获得状态代码为200的预期正文,但在我的执行代码中,相同的请求将返回错误代码400。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
url :="https://accounts.zoho.com/apiauthtoken/nb/create?SCOPE=xxxx&EMAIL_ID=xxxx&PASSWORD=xxxx"

req, err := http.NewRequest("POST", url, nil)
log.Println(err)

res, err := client.Do(req)
log.Println(err)

defer res.Body.Close()
body, err := ioutil.ReadAll(res.Body)
log.Println(err)

fmt.Println(res)
fmt.Println(string(body))

所有错误均为nil,但是res结构包含400 Bad Request,(主体的)最后一个输出为空。

输出:

1
&{400 Bad Request 400 HTTP/1.1 1 1 map[Date:[Sat, 03 Mar 2018 16:48:35 GMT] Connection:[keep-alive] Set-Cookie:[a8c61fa0dc=5f224f2ab9d067cfce10fd0b7fae48bf; Path=/; Secure; HttpOnly] Server:[ZGS]] 0xc04225a080 -1 [chunked] false false map[] 0xc042034a00 0xc0421bc370}

我将不胜感激,因为我不知道此问题来自何处。

  • 使用微服务时,我也遇到了同样的问题。 您可以在使用go run in terminal运行程序时打印应该在控制台上得到的错误输出吗
  • 我更新了问题并添加了输出,但是正如我所说,错误为nil,响应"对象"包含400。

网址编码的参数应在主体参数中提供,而不应作为查询字符串提供。 因此,这也可能是一个问题。 在实现io.Reader的主体中设置参数。

1
func NewRequest(method, url string, body io.Reader) (*Request, error)

在使用Client.Do发送之前,在请求中设置标题Content-Type。

1
req.Header.Set("Content-Type","application/x-www-form-urlencoded")

由于邮递员很聪明,可以为您设置标题。 那就是为什么没有错误。
整个代码变成

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
package main

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

    url :="https://accounts.zoho.com/apiauthtoken/nb/create"

    var data url.Values{}
    data.Set("SCOPE","xxxx")
    data.Add("EMAIL","xxxx")
    data.Add("PASSWORD","xxxx")
    req, err := http.NewRequest("POST", url, strings.NewReader(data.Encode()))
    req.Header.Add("Content-Type","application/x-www-form-urlencoded")

    log.Println(err)

    res, err := client.Do(req)
    log.Println(err)

    defer res.Body.Close()
    body, err := ioutil.ReadAll(res.Body)
    log.Println(err)

    fmt.Println(res)
    fmt.Println(string(body))

}
  • 我已经尝试过设置Content-Type,但是我不知道您需要额外传递url值。 谢谢
  • url.Values{}实际上是类型map[string][]string,它是已创建的Type
  • 您是否知道为什么使用您的方法仍无法通过API发送或接收参数? 当您完全不提供任何参数时,API会发送与发送消息完全相同的消息。 如果任何参数损坏,它将返回特定的错误消息,因此情况并非如此。
  • 您是否会显示错误消息,您是否还能获得发布的参数
  • 这是我从API获得的结果(我希望它的RESULT设置为TRUE,而不是原因返回令牌:# #Tue Mar 06 12:20:41 PST 2018 CAUSE=null RESULT=FALSE我不知道"获取发布的参数"是什么意思。