共计 6217 个字符,预计需要花费 16 分钟才能阅读完成。
1. 怎么实现 HTTP 协定客户端?
Go
语言规范库内置了 net/http
包,涵盖了 HTTP
客户端和服务端具体的实现形式。内置的 net/http
包提供了最简洁的 HTTP
客户端实现形式,毋庸借助第三方网络通信库,就能够间接应用 HTTP
中用得最多的 GET
和POST
形式申请数据。
实现 HTTP
客户端就是客户端通过网络拜访向服务端发送申请,服务端发送响应信息,并将相应信息输入到客户端的过程。实现客户端有以下几种形式。
2.Get 申请
2.1 应用 http.NewRequest
1. 源码
// method:GET | POST
// url:
func NewRequest(method, url string, body io.Reader) (*Request, error) {return NewRequestWithContext(context.Background(), method, url, body)
}
2. 应用示例
package main
import (
"fmt"
"io/ioutil"
"net/http"
)
func main() {testHttpNewRequestByGet()
}
func testHttpNewRequestByGet() {
// 1. 创立一个客户端
client := http.Client{}
// 2. 创立一个申请, 申请形式能够是 GET,也能够是 POST
request, err := http.NewRequest("GET", "https://api.apiopen.top/getJoke?page=1&count=2&type=text", nil)
catchError(err)
// 3. 示范增加 cookie
cookie1 := http.Cookie{Name: "uid", Value: "1001"}
request.AddCookie(&cookie1)
// 4. 发动申请数据
response, err := client.Do(request)
catchError(err)
// 5. 解析返回数据
if response.StatusCode != 200 {fmt.Println("网络申请失败!")
}
// 6. 读取后须要敞开 response.Body
defer func() {response.Body.Close()
}()
// 7. 读取 response.Body
body, err := ioutil.ReadAll(response.Body)
catchError(err)
fmt.Println("申请后果:" + string(body))
}
// 捕捉谬误
func catchError(err error) {
// 应用提早函数捕捉谬误
defer func() {if er := recover(); er != nil {fmt.Println(fmt.Sprintf("零碎解体:%v",er))
}
}()
// 抛出谬误
if err != nil {panic(err)
}
}
2.2 应用 clent.Get
1. 源码
func (c *Client) Get(url string) (resp *Response, err error) {req, err := NewRequest("GET", url, nil)
if err != nil {return nil, err}
return c.Do(req)
}
2. 应用示例
package main
import (
"fmt"
"io/ioutil"
"net/http"
)
func main() {testClientGet()
}
// 测试 client.Get 办法
func testClientGet() {
// 1. 创立客户端
client := http.Client{}
// 2. 调用客户端的 Get 办法
response, err := client.Get("https://api.apiopen.top/getJoke?page=1&count=2&type=text")
catchError(err)
// 3. 解析返回数据
if response.StatusCode != 200 {fmt.Println("网络申请失败!")
}
// 4. 读取后须要敞开 response.Body
defer func() {response.Body.Close()
}()
// 5. 读取 response.Body
res, err := ioutil.ReadAll(response.Body)
catchError(err)
// 6. 打印输出
fmt.Printf("返回后果: %s\n",res)
}
// 捕捉谬误
func catchError(err error) {
// 应用提早函数捕捉谬误
defer func() {if er := recover(); er != nil {fmt.Println(fmt.Sprintf("零碎解体:%v", er))
}
}()
// 抛出谬误
if err != nil {panic(err)
}
}
2.3 应用 http.Get
1. 源码
func Get(url string) (resp *Response, err error) {return DefaultClient.Get(url)
}
2. 应用示例
package main
import (
"fmt"
"io/ioutil"
"net/http"
)
func main() {testClientGet()
}
// 测试 client.Get 办法
func testClientGet() {
// 1. 间接调用 http.Get
response, err := http.Get("https://api.apiopen.top/getJoke?page=1&count=2&type=text")
catchError(err)
// 2. 解析返回数据
if response.StatusCode != 200 {fmt.Println("网络申请失败!")
}
// 3. 读取后须要敞开 response.Body
defer func() {response.Body.Close()
}()
// 4. 读取 response.Body
res, err := ioutil.ReadAll(response.Body)
catchError(err)
// 5. 打印输出
fmt.Printf("返回后果: %s\n",res)
}
// 捕捉谬误
func catchError(err error) {
// 应用提早函数捕捉谬误
defer func() {if er := recover(); er != nil {fmt.Println(fmt.Sprintf("零碎解体:%v", er))
}
}()
// 抛出谬误
if err != nil {panic(err)
}
}
3.Post 申请
3.1 应用 http.NewRequest
1. 应用示例
package main
import (
"fmt"
"io/ioutil"
"net/http"
"strings"
)
func main() {testHttpNewRequestByPost()
}
func testHttpNewRequestByPost() {
// 1. 创立一个客户端
client := http.Client{}
// 2. 增加参数, 并将参数转成 io.Reader 类型
paramStr := "userName=admin&passWord=1234"
// 3. 创立一个 POST 申请
request, err := http.NewRequest("POST", "http://127.0.0.1:8888/login", strings.NewReader(paramStr))
catchError(err)
// 4. 增加 header 头
request.Header.Add("Content-Type","application/x-www-form-urlencoded")
// 5. 设置 cookie 示例
request.Header.Set("Cookie","uid=199")
// 6. 发动申请数据
response, err := client.Do(request)
catchError(err)
// 7. 解析返回数据
if response.StatusCode != 200 {fmt.Println("网络申请失败!")
}
// 8. 读取后须要敞开 response.Body
defer func() {response.Body.Close()
}()
// 9. 读取 response.Body
body, err := ioutil.ReadAll(response.Body)
catchError(err)
fmt.Println("申请后果:" + string(body))
}
// 捕捉谬误
func catchError(err error) {
// 应用提早函数捕捉谬误
defer func() {if er := recover(); er != nil {fmt.Println(fmt.Sprintf("零碎解体:%v",er))
}
}()
// 抛出谬误
if err != nil {panic(err)
}
}
3.2 应用 client.Post 或 client.PostForm
1. 源码
//client.Post
func (c *Client) Post(url, contentType string, body io.Reader) (resp *Response, err error) {req, err := NewRequest("POST", url, body)
if err != nil {return nil, err}
req.Header.Set("Content-Type", contentType)
return c.Do(req)
}
// client.PostForm
func (c *Client) PostForm(url string, data url.Values) (resp *Response, err error) {return c.Post(url, "application/x-www-form-urlencoded", strings.NewReader(data.Encode()))
}
2. 应用示例
package main
import (
"fmt"
"io/ioutil"
"net/http"
"net/url"
"strings"
)
func main() {
reqType := 2
// 1. 创立一个客户端
client := http.Client{}
var response *http.Response
var err error
if reqType == 1{
// 2. 增加参数, 参数类型为 io.Reader
paramStr := "userName=admin&passWord=1234"
// 3. 创立一个申请, 申请形式能够是 GET,也能够是 POST
response, err = client.Post("http://127.0.0.1:8888/login","application/x-www-form-urlencoded", strings.NewReader(paramStr))
} else {
// 2. 增加参数, 参数类型为 url.Values
param := url.Values{"userName": []string{"admin"},
"passWord": []string{"1234"},
}
// 3. 创立一个 POST 申请
response, err = client.PostForm("http://127.0.0.1:8888/login", param)
}
catchError(err)
// 4. 解析返回数据
if response.StatusCode != 200 {fmt.Println("网络申请失败!")
}
// 5. 读取后须要敞开 response.Body
defer func() {response.Body.Close()
}()
// 6. 读取 response.Body
body, err := ioutil.ReadAll(response.Body)
catchError(err)
fmt.Println("申请后果:" + string(body))
}
// 捕捉谬误
func catchError(err error) {
// 应用提早函数捕捉谬误
defer func() {if er := recover(); er != nil {fmt.Println(fmt.Sprintf("零碎解体:%v",er))
}
}()
// 抛出谬误
if err != nil {panic(err)
}
}
3.3 应用 http.Post 或 http.PostForm
1. 源码
// http.Post
func Post(url, contentType string, body io.Reader) (resp *Response, err error) {return DefaultClient.Post(url, contentType, body)
}
// http.PostForm
func PostForm(url string, data url.Values) (resp *Response, err error) {return DefaultClient.PostForm(url, data)
}
2. 应用示例
package main
import (
"fmt"
"io/ioutil"
"net/http"
"net/url"
"strings"
)
func main() {
reqType := 1
var response *http.Response
var err error
if reqType == 1{
// 1. 增加参数, 参数类型为 io.Reader
paramStr := "userName=admin&passWord=1234"
// 2. 创立一个申请, 申请形式能够是 GET,也能够是 POST
response, err = http.Post("http://127.0.0.1:8888/login","application/x-www-form-urlencoded", strings.NewReader(paramStr))
} else {
// 1. 增加参数, 参数类型为 url.Values
param := url.Values{"userName": {"admin"},
"passWord": []string{"1234"},
}
// 2. 创立一个 POST 申请
response, err = http.PostForm("http://127.0.0.1:8888/login", param)
}
catchError(err)
// 3. 解析返回数据
if response.StatusCode != 200 {fmt.Println("网络申请失败!")
}
// 4. 读取后须要敞开 response.Body
defer func() {response.Body.Close()
}()
// 5
//. 读取 response.Body
body, err := ioutil.ReadAll(response.Body)
catchError(err)
fmt.Println("申请后果:" + string(body))
}
// 捕捉谬误
func catchError(err error) {
// 应用提早函数捕捉谬误
defer func() {if er := recover(); er != nil {fmt.Println(fmt.Sprintf("零碎解体:%v",er))
}
}()
// 抛出谬误
if err != nil {panic(err)
}
}
本文由 mdnice 多平台公布
正文完