Go 语言快速入门指南:GET 和 POST 方法
介绍
超文本传输协议(HTTP)客户端用于建立连接并向 HTTP 服务器请求数据。最常见的方法是 GET
和 POST
。
在 Go 中,我们使用 http
包来创建 GET 和 POST 请求。该包提供 HTTP 客户端和服务器实现。
http
包支持 RFC 2616 中定义的属性,如超时、重定向和 cookies。虽然这个包有更多的基本方法,比如http.Client.Get()
和 http.Client.Post()
方法,但为了应用自定义头信息,http.NewRequest()
函数可以和 http.Client.Do()
方法一起使用。本章演示了 GET
和 POST
请求,通过使用更常见的功能的例子,如客户端超时、cookies和自定义头信息。
GET 请求
HTTP GET 方法请求指定资源的表示,使用 GET 的请求应该只检索数据。一个简单的 GET 请求可以用 http.Client.Get()
方法完成:
package main
import (
"fmt"
"io/ioutil"
"log"
"net/http"
)
func main() {
resp, err := http.Get("https://www.baidu.com")
if err != nil {
log.Fatal(err)
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
log.Fatal(err)
}
fmt.Println(string(body))
}
在 main
函数中,它向 www.baidu.com
发送了一个 GET 请求,并从响应中读取了响应体。如果在发送请求或读取响应体的过程中出现错误,程序将会调用 log.Fatal
函数打印错误信息并退出。
io.ReadAll()
函数将整个响应主体读入一个字节片中。然后,您可以将字节切片转换为字符串并将其打印出来。
最后,程序将响应体转换成字符串并打印到控制台上。
如果需要自定义头信息,可以使用 http.NewRequest()
函数和 http.Client.Do()
方法的组合。
req, err := http.NewRequest("GET", "http://www.baidu.com/", nil)
if err != nil {
// handle error
}
req.Header.Set("User-Agent", "MyUserAgent/1.0")
http.NewRequest
函数采用三个参数:HTTP 方法、URL 和请求正文。在此示例中,我们正在创建一个没有请求正文的 GET 请求。
然后,您可以使用 *http.Request
对象的 Header
字段为请求设置标头。在此示例中,我们正在设置 User-Agent
标头。
package main
import (
"fmt"
"io/ioutil"
"log"
"net/http"
)
func main() {
client := &http.Client{}
req, err := http.NewRequest("GET", "https://www.baidu.com", nil)
if err != nil {
log.Println(err)
return
}
req.Header.Add("If-None-Match", `W/"wyzzy"`)
resp, err := client.Do(req)
if err != nil {
log.Println(err)
return
}
defer resp.Body.Close()
recv, err := ioutil.ReadAll(resp.Body)
if err != nil {
log.Fatal(err)
return
}
fmt.Printf("%s", recv)
}
运行 go run main.go
,输出结果:
自定义 Header
req.Header.Add("user-agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_0)")
POST 请求
Go 语言中的 http.NewRequest
函数创建一个 HTTP POST 请求,其中第一个参数是 HTTP 请求方法,第二个参数是 POST 请求的URL(在此例中为 www.baidu.com
),第三个参数是请求数据(JSON 数据)。此外,还设置了HTTP请求头 Content-Type 为 application/json
。最后,创建一个客户端并使用 client.Do(request)
方法进行 POST 请求。
要发送请求,您可以使用 http.DefaultClient.Do
函数:
resp, err := http.DefaultClient.Do(req)
if err != nil {
// handle error
}
defer resp.Body.Close()
在 REST API 中,GET 请求仅用于从服务器检索信息,因此为了使程序完全参与 REST API,程序还需要支持发送 POST 请求。POST 请求几乎是 GET 请求的相反,客户端在请求正文中向服务器发送数据。为了实现这一点,需要更新程序,将请求发送为 POST 请求,包括请求正文,并更新服务器以打印有关客户端请求的更多信息。
package main
import (
"bytes"
"encoding/json"
"fmt"
"io/ioutil"
"log"
"net/http"
)
func main() {
values := map[string]string{"foo": "baz"}
jsonData, err := json.Marshal(values)
req, err := http.NewRequest(http.MethodPost, "https://httpbin.org/post", bytes.NewBuffer(jsonData))
if err != nil {
log.Fatal(err)
}
// appending to existing query args
q := req.URL.Query()
q.Add("foo", "bar")
// assign encoded query string to http request
req.URL.RawQuery = q.Encode()
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
fmt.Println("Errored when sending request to the server")
return
}
defer resp.Body.Close()
responseBody, err := ioutil.ReadAll(resp.Body)
if err != nil {
log.Fatal(err)
}
fmt.Println(resp.Status)
fmt.Println(string(responseBody))
}
在这个例子中,方法、URL 和正文是用 http.NewRequest()
函数设置的,以便接收一个 http.Request
对象。然后,用 http.Request.Header.Set()
方法设置一个头,使用标准键值对作为输入。接下来,在 http.Client
结构中初始化 Timeout 字段,并返回一个新的 http.Client
对象。现在,GET 请求是用 URL 建立的,客户端头也被定义了,它们与自定义超时一起被用于
和自定义超时来发送和接收 HTTP 请求,使用 http.Client.Do()
方法发送和接收 HTTP 请求。最后,响应对象被从 最后,从 http.Client.Do()
方法中接收响应对象,并在打印响应之前关闭请求体响应。
HTTP POST 方法向服务器发送数据。它通常在上传文件或提交一个完整的网络表格时使用。
HTTP 1.1 协议支持 HTTP 持久连接,也称为 HTTP Keep-Alive。这允许客户端和服务器在发送多个 HTTP 请求/响应时重用相同的基础 TCP 连接。因此,客户端不是为每个 HTTP 请求建立连接,而是重复使用先前创建的 TCP 连接。这在性能方面特别有用,当向同一主机发送多个请求时尤其如此。
在整个代码库中重复使用 http.Client
。它的一个例子如下:
package main
import (
"bytes"
"io/ioutil"
"log"
"net/http"
"time"
)
func httpClient() *http.Client {
client := &http.Client{Timeout: 10 * time.Second}
return client
}
func sendRequest(client *http.Client, method string) []byte {
endpoint := "https://httpbin.org/post"
values := map[string]string{"foo": "baz"}
jsonData, err := json.Marshal(values)
req, err := http.NewRequest(method, endpoint, bytes.NewBuffer(jsonData))
if err != nil {
log.Fatalf("Error Occurred. %+v", err)
}
response, err := client.Do(req)
if err != nil {
log.Fatalf("Error sending request to API endpoint. %+v", err)
}
// Close the connection to reuse it
defer response.Body.Close()
body, err := ioutil.ReadAll(response.Body)
if err != nil {
log.Fatalf("Couldn't parse response body. %+v", err)
}
return body
}
func main() {
// c should be re-used for further calls
c := httpClient()
response := sendRequest(c, http.MethodPost)
log.Println("Response Body:", string(response))
}
总结
net/http
包向该服务器发出 HTTP 请求。首先,您使用 http.Get
函数通过 Go 的默认 HTTP 客户端向服务器发出 GET 请求。然后,您使用 http.NewRequest
和 http.DefaultClient
的 Do()
方法发出 GET 请求。
最后,您在 http.Request
的 Header 字段上使用了 Set 方法来设置请求的 Content-Type 标头,并通过创建您自己的 HTTP 客户端而不是使用 Go 的默认客户端来设置请求持续时间的 30 秒超时。 net/http
包不仅仅包含您在本教程中使用的功能。它还包含一个 http.Post
函数,可用于发出 POST 请求,类似于 http.Get
函数。该软件包还支持保存和检索 cookie 等功能。
参考链接:
- 点赞
- 收藏
- 关注作者
评论(0)