【问题标题】:How do I handle plain text HTTP Get response in Golang?如何在 Golang 中处理纯文本 HTTP Get 响应?
【发布时间】: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

【问题讨论】:

    标签: rest http go


    【解决方案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())
    

    【讨论】:

      猜你喜欢
      • 2013-07-27
      • 2015-03-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-09-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多