首页 > 解决方案 > 用http.NewRequest调用rest API时,响应体乱码

问题描述

我尝试用 Go 调用 API。使用 Postman 时一切正常。但是,如果我使用 Postman 的 Go 代码,则响应会出现乱码/不清楚。

在我正在使用的代码下方:

func CallAPI() {
    url := "https://url"

    req, _ := http.NewRequest("GET", url, nil)

    req.Header.Add("Authorization", "Bearer Token is normaly here")
    req.Header.Add("User-Agent", "PostmanRuntime/7.19.0")
    req.Header.Add("Accept", "Accept: application/json")
    req.Header.Add("Cache-Control", "no-cache")
    req.Header.Add("Postman-Token", "Postman token normaly here")
    req.Header.Add("Host", "host normaly here")
    req.Header.Add("Accept-Encoding", "gzip, deflate")
    req.Header.Add("Connection", "keep-alive")
    req.Header.Add("cache-control", "no-cache")

    res, _ := http.DefaultClient.Do(req)

    defer res.Body.Close()
    body, _ := ioutil.ReadAll(res.Body)


    fmt.Println(string(body))
}

我使用时得到的响应fmt.Println(string(body))如下所示。我还使用此代码尝试了其他 API,并得到了相同的结果。

r�痱� 

我还尝试将 json 解组为结构并确实收到以下错误 Invalid character '\x1f' looking for beginning of value

我认为这与解码有关。但我不知道是什么。

标签: apihttpgo

解决方案


您要求服务器发送压缩的内容 ( req.Header.Add("Accept-Encoding", "gzip, deflate")),这就是您得到的:一个 gzip 响应,由响应标头指示:Content-Encoding:[gzip]

删除该标头(不要设置Accept-Encoding请求标头),您应该会得到纯 JSON 响应。或者自己解码 gzip 响应。

请注意,如果您省略此标头,默认传输仍将请求gzip编码,但它也会透明地对其进行解码。由于您明确请求它,因此不会发生透明的自动解码。这记录在Transport.DisableCompression现场:

// DisableCompression, if true, prevents the Transport from
// requesting compression with an "Accept-Encoding: gzip"
// request header when the Request contains no existing
// Accept-Encoding value. If the Transport requests gzip on
// its own and gets a gzipped response, it's transparently
// decoded in the Response.Body. However, if the user
// explicitly requested gzip it is not automatically
// uncompressed.
DisableCompression bool

推荐阅读