Skip to content

Go语言请求Http

更新: 11/16/2024 字数: 0 字 时长: 0 分钟

快速开始

Get请求

go
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
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.Gethttp.Post方法本质是使用了http包下的一个默认client

net/http/client.go
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
go
// 5s超时的client
client := &http.Client{Timeout: 5 * time.Second}

创建请求

1. 创建request

我们会创建一个request对象来储存相关的请求数据,我们这里的视角是客户端。

这个对象不止是客户端在用,服务端也在用(例如gin),所以有些参数并不会生效。

WARNING

请勿轻易修改在创建时传入的参数,除非你读懂了源码的操作逻辑,并确认修改后不会影响结果!!

go
go
req, err := http.NewRequest(method, url, body)

2. 修改url参数(包含请求参数)

url属性会根据传入的url自动解析,也可以二次修改

go
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
go
req.Header.Add("foo3", "bar3")

3. 修改cookie

cookie本质还是通过header存储,所以可以直接添加在header中

go
go
req.Header.Add("cookie", "foo2=bar2")

开始请求

可以直接使用client的方法进行请求

go
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
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")
}