使用Golang实现高效的HTTP GET请求发送与数据处理详解
一、HTTP GET请求基础
二、Go语言net/http
包简介
http.Client
:表示HTTP客户端,用于发送请求。http.NewRequest
:用于创建新的HTTP请求。http.Get
:用于发送GET请求的便捷函数。http.Response
:表示HTTP响应。
三、发送HTTP GET请求
1. 使用http.Get
函数
package main
import (
"fmt"
"io/ioutil"
"net/http"
)
func main() {
url := "https://api.example.com/data"
resp, err := http.Get(url)
if err != nil {
fmt.Println("请求发送失败:", err)
return
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
fmt.Println("读取响应失败:", err)
return
}
fmt.Println("响应内容:", string(body))
}
2. 使用http.NewRequest
和http.Client
package main
import (
"fmt"
"io/ioutil"
"net/http"
)
func main() {
url := "https://api.example.com/data"
client := &http.Client{}
req, err := http.NewRequest("GET", url, nil)
if err != nil {
fmt.Println("创建请求失败:", err)
return
}
// 设置请求头
req.Header.Set("User-Agent", "MyApp/1.0")
resp, err := client.Do(req)
if err != nil {
fmt.Println("请求发送失败:", err)
return
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
fmt.Println("读取响应失败:", err)
return
}
fmt.Println("响应内容:", string(body))
}
四、处理HTTP响应
1. 读取响应体
如上所示,我们可以使用ioutil.ReadAll
函数来读取响应体内容。这是一种简单直接的方式,但请注意,对于大型响应体,这种方式可能会导致内存消耗过大。
2. 处理响应头
HTTP响应头包含了丰富的信息,如内容类型、服务器信息等。我们可以通过resp.Header
来访问这些信息。
contentType := resp.Header.Get("Content-Type")
fmt.Println("Content-Type:", contentType)
3. 处理状态码
HTTP状态码表示请求的处理结果。我们可以通过resp.StatusCode
来获取状态码,并根据需要进行处理。
if resp.StatusCode != http.StatusOK {
fmt.Printf("请求失败,状态码:%d\n", resp.StatusCode)
return
}
五、高效数据处理
1. 流式读取
对于大型数据,流式读取是一种更高效的方式。我们可以使用resp.Body
作为一个io.Reader
来逐块读取数据。
package main
import (
"fmt"
"io"
"net/http"
)
func main() {
url := "https://api.example.com/large-data"
resp, err := http.Get(url)
if err != nil {
fmt.Println("请求发送失败:", err)
return
}
defer resp.Body.Close()
buf := make([]byte, 1024)
for {
n, err := resp.Body.Read(buf)
if err != nil && err != io.EOF {
fmt.Println("读取响应失败:", err)
return
}
if n == 0 {
break
}
fmt.Println(string(buf[:n]))
}
}
2. 并发处理
Go语言的并发特性使得我们可以在处理多个HTTP请求时提高效率。我们可以使用goroutine
来并发发送请求。
package main
import (
"fmt"
"io/ioutil"
"net/http"
"sync"
)
func fetchURL(url string, wg *sync.WaitGroup) {
defer wg.Done()
resp, err := http.Get(url)
if err != nil {
fmt.Println("请求发送失败:", err)
return
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
fmt.Println("读取响应失败:", err)
return
}
fmt.Printf("URL: %s, 响应内容: %s\n", url, string(body))
}
func main() {
urls := []string{
"https://api.example.com/data1",
"https://api.example.com/data2",
"https://api.example.com/data3",
}
var wg sync.WaitGroup
for _, url := range urls {
wg.Add(1)
go fetchURL(url, &wg)
}
wg.Wait()
}