从 http 响应正文读取 golang
Posted
技术标签:
【中文标题】从 http 响应正文读取 golang【英文标题】:Reading on golang from http responce body 【发布时间】:2017-12-18 08:14:58 【问题描述】:我向服务器发送请求并从其中获得答案。你可以看到我的代码:
// Some code
queryUrl, err := url.Parse(someValidStringUrl)
resp, err := client.Get(queryUrl.String())
我们来看看err
:
if err != nil
log.Panic("Responce:", resp, "\nError:", err)
在此之后,我想得到我的回复正文。我这样做了,但我得到了空字节片:
var bytes []byte
n, err := resp.Body.Read(bytes)
if err != nil
log.Panic(err)
log.Println(n, string(bytes))
输出示例:
2017/07/13 16:32:36 0
Here我找到了另一种方式:
// Some code
queryUrl, err := url.Parse(someValidStringUrl)
resp, err := client.Get(queryUrl.String())
if err != nil
log.Panic("Responce:", resp, "\nError:", err)
defer resp.Body.Close()
if resp.StatusCode == 200 // OK
bodyBytes, err := ioutil.ReadAll(resp.Body)
if err != nil
log.Panic(err)
log.Println(string(bodyBytes))
输出示例:
<html lang='en'>
<head>
</head>
<body>
<title>Hello world</title>
</body>
</html>
请帮帮我。这些例子之间有什么区别?为什么我的方法行不通?
【问题讨论】:
【参考方案1】:来自 Golang 的Reader documentation
Read 最多将 len(p) 个字节读入 p。它返回读取的字节数 (0
当 Read 在成功读取 n > 0 个字节后遇到错误或文件结束条件时,它返回读取的字节数。它可能会从同一次调用中返回(非零)错误,或者从后续调用中返回错误(并且 n == 0)。这种一般情况的一个例子是,在输入流末尾返回非零字节数的 Reader 可能会返回 err == EOF 或 err == nil。下一次读取应该返回 0,EOF。
//Reader interface from package documentation showing 'p' is the input byte slice.
type Reader interface
Read(p []byte) (n int, err error)
由于您从未初始化切片,len(bytes)
始终为 0,因此它只读取 0 个字节。要像您尝试那样手动执行此操作,您必须将切片初始化为非空,然后多次调用 read 直到它最终返回 0 和 EOF,同时将字节附加到您维护的某个缓冲区。这就是为什么需要ioutil.ReadAll 的原因,它保证所有内容都被正确读取,您不必担心处理它。
还要注意示例中的defer resp.Body.Close()
。请务必记住在使用 Readers 和 Writers 后关闭它们。
【讨论】:
【参考方案2】:响应正文是 Reader。根据文档:
Read 最多将 len(p) 个字节读入 p。它返回字节数 读取 (0
由于当您将字节切片 var bytes []byte
传递给 Read 时,它的长度为 0,因此它永远不会返回任何字节。
您可以做的是将您的 []byte 初始化为与返回的内容相同的大小:
bytes := make([]byte, resp.ContentLength)
或者,只需使用 ioutil.ReadAll。
【讨论】:
不保证Content-Length
是正确的以上是关于从 http 响应正文读取 golang的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 Golang 的 net/http 包读取流响应正文?