golang 发送 http请求

539 阅读1分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第4天。

做个分享

起因是今天闲着想去写一下微信小程序服务端代码,然后需要在后台请求微信api。一般用go做响应服务器时,我都是用gin框架。请求服务的话,内置的net/http包就能满足了。

go version 1.19

简单的请求

对于简单的不带任何参数的请求,可以直接使用封装好的简便方法。

res,err := http.Get("https://baidu.com")
if err != nil{
    //TODO
    fmt.Println("err: ", err)
}
defer res.Body.Close()
b, _ := ioutil.ReadAll(res.Body)
fmt.Println(string(b))

复杂一点的请求

对于一些请求,我们大多数情况下会带有一些参数,还可能会设置一些请求头信息字段,这时可以使用NewRequest 或者自己构建请求url来实现。简洁一下,下面的代码不做错误处理。

req,_ := http.NewRequest("GET","http://baidu.com,nil)
params := url.Values{}

params.Set("key1","value1")
params.Set("key2","value2")
req.URL.RawQuery = params.Encode()

r, err := http.DefaultClient.Do(req)

先使用http.NewRequest构建一个http请求,使用url.Values设置请求参数,最后发起请求。下面是第二种封装方法。params.Encode会对中文进行URIEncode编码。

params := url.Values{}
parseURL, _ := url.Parse("http://baidu.com")

params.Set(key, value)
parseURL.RawQuery = params.Encode()
urlPathWithParams := parseURL.String()
res, err := http.Get(urlPathWithParams)
if err != nil {
    return result, err
}
defer res.Body.Close()
b, _ := ioutil.ReadAll(res.Body)

添加请求头、cookies

有时候也会需要添加请求头字段,携带一些cookie值,代码中req都是代表请求。

client := http.Client{}
req,_ := http.NewRequest("GET","xxx.com",nil)

req.Header.Add("Content-Type","application/json;charset=utf-8")
req.Header.Add("Custom-header","hahaha")

cookies := &http.Cookie{
    name: "zs",
    age: 220
}
req.AddCookie(cookies)

完整示例封装

type Client[T any] struct {
    url    string
    params map[string]string
}

func (c *Client[T]) Get() (result T, err error) {
    params := url.Values{}
    parseURL, _ := url.Parse(c.url)
    for key, value := range c.params {
        params.Set(key, value)
    }
    parseURL.RawQuery = params.Encode()
    urlPathWithParams := parseURL.String()
    res, err := http.Get(urlPathWithParams)
    if err != nil {
	return result, err
    }
    defer res.Body.Close()
    b, _ := ioutil.ReadAll(res.Body)
    json.Unmarshal(b, &result)
    return
}

我使用的版本是1.19.2,所以封装的时候使用了泛型,如果版本低于1.18的话,可以去掉泛型。