如何在 Golang 中处理纯文本 HTTP Get 响应?

Posted

技术标签:

【中文标题】如何在 Golang 中处理纯文本 HTTP Get 响应?【英文标题】:How do I handle plain text HTTP Get response in Golang? 【发布时间】:2016-08-06 19:16:51 【问题描述】:

我正在向返回纯文本响应的端点发出 HTTP GET 请求。

如何获取纯文本响应的字符串?

我的代码如下所示:

url := "http://someurl.com"

response, err := http.Get(url)
if err != nil 
    log.Fatal(err)

defer response.Body.Close()
responseString := //NOT SURE HOW TO GRAB THE PLAIN TEXT STRING

【问题讨论】:

【参考方案1】:

可以使用任何可以从传入字节流中读取数据的方法来读取正文的响应。其中最简单的是ioutil包中提供的ReadAll函数。

responseData,err := ioutil.ReadAll(response.Body)
if err != nil 
    log.Fatal(err)

它会在 []byte 中为您提供 API 响应。如果响应是纯文本,您可以使用类型转换轻松地将其转换为字符串:

responseString := string(responseData)

然后检查结果

fmt.Println(responseString)

示例程序:

package main

import (
    "fmt"
    "io/ioutil"
    "log"
    "net/http"
)

func main() 
    url := "http://country.io/capital.json"
    response, err := http.Get(url)
    if err != nil 
        log.Fatal(err)
    
    defer response.Body.Close()

    responseData, err := ioutil.ReadAll(response.Body)
    if err != nil 
        log.Fatal(err)
    

    responseString := string(responseData)

    fmt.Println(responseString)

【讨论】:

如果您获得的网页包含(例如)西班牙语/意大利语/等。字符,将[]byte 转换为string 不会得到好的结果。确切地说,éá 等字符会得到 � 字符。您需要迭代 responseData 并连接每个字符。一种优化的方式是this ;-) @Amd 的回答解决了 Unicode 文本的问题,方法与我之前的评论相同,但是,我认为更好 ;-) @ToniVillena "spanish/italian/etc. characters, you won't get a good result in convert of []byte to string" — 这是不正确的。如果你有一个有效的 UTF-8 字节切片,如果你 io.ReadAll 一个 UTF-8 编码的 HTTP 响应,你可以直接打印 convert []byte to string。见playground。另一方面,如果你错误地/手动地构造了一个像this example 这样的字节片,那么你会得到...。【参考方案2】:

使用ioutil.ReadAll(response.Body)

你也可以使用bufio.NewScanner(response.Body)处理Unicode文本 像这个工作示例代码:

package main

import (
    "bufio"
    "bytes"
    "fmt"
    "log"
    "net/http"
)

func main() 
    response, err := http.Get("http://127.0.0.1")
    if err != nil 
        log.Fatal(err)
    
    defer response.Body.Close()

    scanner := bufio.NewScanner(response.Body)
    scanner.Split(bufio.ScanRunes)
    var buf bytes.Buffer
    for scanner.Scan() 
        buf.WriteString(scanner.Text())
    
    fmt.Println(buf.String())

输出:

*Hello World* B=µH *

使用此示例 Web 服务器代码:

package main

import (
    "fmt"
    "log"
    "net/http"
)

func ServeHTTP(w http.ResponseWriter, r *http.Request) 
    body := "*Hello World* B=µH *"
    fmt.Fprint(w, body)


func main() 
    http.HandleFunc("/", ServeHTTP)
    if err := http.ListenAndServe(":80", nil); err != nil 
        log.Fatal(err)
    

【讨论】:

感谢@Amd 的回答! ,我不知道将Unicode文本的字节数组解码为字符串的方法,对我来说很头疼... :-) @ToniVillena 感谢鼓励 我认为您不需要像这个答案那样阅读单个符文。在 Mayank Patel 的回答中查看我对 ToniVillena 的回复。【参考方案3】:

使用io.Copy,您可以从 io.Reader 读取所有字节,并将其写入 io.Writer

resp, err := http.Get(server.URL + "/v1/ping")
if err != nil 
    t.Errorf("failed to execute GET request: %s", err)

defer resp.Body.Close()

var b bytes.Buffer
if _, err := io.Copy(&b, resp.Body); err != nil 
    t.Errorf("failed to copy response body: %s", err)


fmt.Println(b.String())

【讨论】:

以上是关于如何在 Golang 中处理纯文本 HTTP Get 响应?的主要内容,如果未能解决你的问题,请参考以下文章

Golang:如何使用 DES 和 CBC 加密 5 个字符长的纯文本?

纯golang爬虫实战(二)

如何记录文本在页面上的位置?

如何在纯文本 XML 中分配角色/权限

当内容类型为文本/纯文本时,.NET Core 1.0 Web Api 将请求正文处理为 JSON

ThymeLeaf 中的条件文本:如何以纯文本形式进行?