Go语言请求Http
更新: 11/16/2024 字数: 0 字 时长: 0 分钟
快速开始
Get请求
go
resp, err := http.Get("http://localhost:5678/api")
if err != nil {
panic(err)
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
panic(err)
}
fmt.Println(string(body))
POST请求
go
// 第二参数为content-type,第三个参数为body,类型为io.Reader
resp, err := http.Post("http://localhost:5678/api", "application/json", strings.NewReader("{\"msg\":\"post body\"}"))
if err != nil {
panic(err)
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
panic(err)
}
fmt.Println(string(body))
复杂请求
go语言原生的http请求的方式是创建一个client,然后使用这个client来请求
定义client
http.Get
和http.Post
方法本质是使用了http包下的一个默认client
go
// net/http/client.go
type Client struct {
Transport RoundTripper
CheckRedirect func(req *Request, via []*Request) error
Jar CookieJar
Timeout time.Duration
}
var DefaultClient = &Client{}
func Get(url string) (resp *Response, err error) {
return DefaultClient.Get(url)
}
func Post(url, contentType string, body io.Reader) (resp *Response, err error) {
return DefaultClient.Post(url, contentType, body)
}
我们也可以定义自己的client
go
// 5s超时的client
client := &http.Client{Timeout: 5 * time.Second}
创建请求
1. 创建request
我们会创建一个request对象来储存相关的请求数据,我们这里的视角是客户端。
这个对象不止是客户端在用,服务端也在用(例如gin),所以有些参数并不会生效。
WARNING
请勿轻易修改在创建时传入的参数,除非你读懂了源码的操作逻辑,并确认修改后不会影响结果!!
go
req, err := http.NewRequest(method, url, body)
2. 修改url参数(包含请求参数)
url属性会根据传入的url自动解析,也可以二次修改
go
// 修改协议
req.URL.Scheme = “https”
// 修改路径
req.URL.Path = “/api/test”
// 修改host
req.URL.Host = “localhost:5678”
// 修改请求参数,这里使用url.Values,他可以自动匹配多种请求参数,比如数组等情况
// Encode()可以自动转码特殊字符和中文
query := &url.Values{}
query.Add("foo1", "bar1")
req.URL.RawQuery = query.Encode()
3. 修改header
go
req.Header.Add("foo3", "bar3")
3. 修改cookie
cookie本质还是通过header存储,所以可以直接添加在header中
go
req.Header.Add("cookie", "foo2=bar2")
开始请求
可以直接使用client的方法进行请求
go
// GET
resp, err := client.Get(url)
// POST
resp, err := client.Post(url, contentType, body)
// HEAD
resp, err := client.Head(url)
以上方法的原形其实是使用client.Do
方法,该方法更全能,而且可以使用我们创建的req
go
resp, err := client.Do(req)
完整代码和测试结果
请求代码
go
client := &http.Client{Timeout: 5 * time.Second}
req, err := http.NewRequest("POST", "http://localhost:5678/api", strings.NewReader("{\"msg\":\"post body\"}"))
if err != nil {
panic(err)
}
query := &url.Values{}
query.Add("foo1", "bar1")
req.URL.RawQuery = query.Encode()
req.Header.Add("content-type", "application/json")
req.Header.Add("cookie", "foo2=bar2")
req.Header.Add("foo3", "bar3")
resp, err := client.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
panic(err)
}
fmt.Println(string(body))
go
package main
import (
"fmt"
"github.com/gin-gonic/gin"
)
type POSTBody struct {
Msg string `json:"msg"`
}
func main() {
r := gin.Default()
r.POST("/api", func(c *gin.Context) {
body := &POSTBody{}
c.Bind(body)
cookie, _ := c.Cookie("foo2")
c.JSON(200, gin.H{
"message": fmt.Sprintf("your msg: %s", body.Msg),
"query.foo1": c.Query("foo1"),
"cookie.foo2": cookie,
"header.foo3": c.GetHeader("foo3"),
})
})
r.Run(":5678")
}