微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Golang request.Body.Close() 返回一个空的 Document

如何解决Golang request.Body.Close() 返回一个空的 Document

我在 2 个不同的包中有 2 个方法,其中 func B() 使用一个 url 读取网页并返回 *html.Tokenizer。但问题是,它工作正常只有当我评论 defer r.Body.Close() 时,如果我启用它,则从 func B 返回的这个文档是空的。

如果这两个函数合并在一个函数中,它也可以工作。但我需要 2 个不同的包装。

在这里缺少什么的任何建议或想法? res.Body 不应该关闭吗?

func  (s ParserService) A(u string) (*domain.Result,error) {
    doc,err := s.B("https://www.google.com/")
    if err != nil {
        fmt.Println(err.Error())
    }
    for tokenType := doc.Next(); tokenType != html.ErrorToken; {
        token := doc.Token()
        fmt.Println(token)
        tokenType = doc.Next()
    }
}

func (c Downloader) B(url string) (*html.Tokenizer,error) {
    r,err := c.httpClient.Get(url)
    if err != nil {
        return nil,err
    }
//    defer r.Body.Close()
    doc := html.NewTokenizer(r.Body)
    return doc,nil
}

解决方法

tl;博士

html.TokenierNext 方法直接从读取器读取。在通过分词器完成处理之前不要关闭正文。在您的示例中,您应该在同一函数中执行 HTTP 请求并标记正文,然后您可以取消对延迟关闭的注释。

详情

html.Tokenizer 接受 io.Reader,分词器将从中读取,直到收到 io.EOF 错误。这个“错误”表明没有任何东西可以读取并且标记器源已完成。

http.Request.Body 是一个 io.ReadCloser,它是 io.Readerio.Closer 的组合。调用 Close 后会发生什么是特定于实现的,但是对于 http.Request.Body,调用 close 后无法从读取器读取更多字节。

您的问题最终是由于过早关闭了 http.Request.Body (io.ReadCloser)。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。