Golang中http标准库中那些客户端功能 | 青训营笔记

207 阅读5分钟

这是我参与「第三届青训营 -后端场」笔记创作活动的的第7篇笔记

😆在这里,我对今天的课所新学到的Golang在http标准库中的那些客户端的api做了一次总结

😜Golang的其他知识在哪里找呢,那你就问对了

👨‍💻Golang基础复习 - 掘金 (juejin.cn) 在这里我总结了一些这篇文章没有提到的一些知识

😊如果有小伙伴能想到更多知识,欢迎大家在评论区留言,那么我们就开始吧

👩‍💻👨‍💻哟西,一个棕~

😎😎😎我是小小分割线

Golang在http标准库中不仅有对http服务器的实现,还有对http客户端的实现

服务器实现http server的功能

客户端则实现可以发出http请求并解析收到的响应的功能

Get

get请求是我们很常用的请求方式

我们来看一下在Golang的http标准库中如何调用api进行发送get请求的实现

首先是

不带参数的get请求

调用http.Get()这个api,它的实现为

func Get(url string) (resp *Response, err error) {
   return DefaultClient.Get(url)
}

可以看到参数为url字符串,返回值则为一个响应对象和一个error

我们可以这样调用

func main() {
   testGet()
}

func testGet() {
   url := "https://search.bilibili.com/all"

   // 调用api
   response, err := http.Get(url)
   if err != nil {
      log.Fatal("Get_error")
   }
   // 在结束时关闭
   defer response.Body.Close()

   // 使用io工具包读取
   readAll, _ := ioutil.ReadAll(response.Body)

   // 将[]byte转成字符串打印
   fmt.Println(string(readAll))
}

运行结果如下

由于太长,只截取了部分


<!DOCTYPE html><html><head><title data-vue-meta="true">搜索 - 哔哩哔哩_Bilibili</title> <meta data-vue-meta="true" charset="UTF-8"><meta  style="height:56px;line-height:56px;width:12.5%;"><a href="/all">
      综合
      <!----></a></li><li class="v-switcher-header-item" style="height:56px;line-height:56px;width:12.5%;"><a href="/video">
      视频
      <!----></a></li><li class="v-switcher-header-item" style="height:56px;line-height:56px;width:12.5%;"><a href="/bangumi">
      番剧
      <!----></a></li><li class="v-switcher-header-item" style="height:56px;line-height:56px;width:12.5%;"><a href="/pgc">
      影视
      <!----></a></li><li class="v-switcher-header-item" style="height:56px;line-height:56px;width:12.5%;"><a href="/live">
      直播
      <!----></a></li><li class="v-switcher-header-item" style="height:56px;line-height:56px;width:12.5%;"><a href="/article">
      专栏
      <!----></a></li><li class="v-switcher-header-item" style="height:56px;line-height:56px;width:12.5%;"><a href="/topic">
      话题
      <!----></a></li><li class="v-switcher-header-item" style="height:56px;line-height:56px;width:12.5%;"><a href="/upuser">
      

Process finished with exit code 0

我们现在知道了无参数的get请求的发送方式

那我们如何发送

带参数的get请求

我们第一时间可能就会想到使用字符串拼接到url中不就行了?

那其实url包里提供了对应的操作,我们来试试看

func main() {
   testGet()
}

func testGet() {
    
   // 我们的目标:https://search.bilibili.com/all?keyword=Golang

   // 拿到一个map的散列列表
   params := url.Values{}

   // 基础的url
   urlstr := "https://search.bilibili.com/all"

   // Parse 将原始 url 解析为 URL 结构
   Url, _ := url.Parse(urlstr)

   // 设置参数
   params.Set("keyword","Golang语言")

   // 赋值给解析后的url的RawQuery
   // 如果有参数有中文需要Encode
   Url.RawQuery = params.Encode()

   // 调用api
   // 参数为上面Url的string()返回值
   response, err := http.Get(Url.String())
   if err != nil {
      log.Fatal("Get_error")
   }
   // 在结束时关闭
   defer response.Body.Close()

   // 使用io工具包读取
   readAll, _ := ioutil.ReadAll(response.Body)

   // 将[]byte转成字符串打印
   fmt.Println(string(readAll))
}

运行结果为

由于太长,只截取了部分

<!DOCTYPE html><html><head><title data-vue-meta="true">Golang语言-哔哩哔哩_Bilibili</title> <meta data-vue-meta="true" charset="UTF-8" class="router-link-exact-active router-link-active">
      综合
      <!----></a></li><li class="v-switcher-header-item" style="height:56px;line-height:56px;width:12.5%;"><a href="/video?keyword=Golang%E8%AF%AD%E8%A8%80">
      视频
      <!----></a></li><li class="v-switcher-header-item" style="height:56px;line-height:56px;width:12.5%;"><a href="/bangumi?keyword=Golang%E8%AF%AD%E8%A8%80">
      番剧
      <!----></a></li><li class="v-switcher-header-item" style="height:56px;line-height:56px;width:12.5%;"><a href="/pgc?keyword=Golang%E8%AF%AD%E8%A8%80">
      影视
      <!----></a></li><li class="v-switcher-header-item" style="height:56px;line-height:56px;width:12.5%;"><a href="/live?keyword=Golang%E8%AF%AD%E8%A8%80">
      直播
      <!----></a></li><li class="v-switcher-header-item" style="height:56px;line-height:56px;width:12.5%;"><a href="/article?keyword=Golang%E8%AF%AD%E8%A8%80">
      专栏
      <!----></a></li><li class="v-switcher-header-item" style="height:56px;line-height:56px;width:12.5%;"><a href="/topic?keyword=Golang%E8%AF%AD%E8%A8%80">
      话题
      <!----></a></li><li class="v-switcher-header-item" style="height:56px;line-height:56px;width:12.5%;"><a href="/upuser?keyword=Golang%E8%AF%AD%E8%A8%80">
      用户
      <!----></a></li><li class="v-switcher-header-anchor"></li></ul></div></div><div style="display:none;"></div><!----></div></div></div><div class="body-contain"><div id="all-list"><div class="flow-loader" style="position:relative;"><!----><div class="filter-wrap"><ul class="filter-type clearfix" style="display:none;"></ul><ul class="filter-type clearfix" style="display:none;"><!----><!----></ul><a class="fold up" style="display:none;"><span>收起</span><i class="arrow-up"></i></a><a class="fold down" style="display:none;"><span>更多筛选</span><i class="arrow-down"></i></a><div class="load-state"><span class="loading">正在加载...</span></div><div class="filter-wrap_bottom"></div></div><div class="mixin-list"><div type="tips" class="tips-list"></div><!----><!----><!----><!----><!----><!----><!----><!----><!----><ul type="video" class="video-list clearfix"><li class="video-item matrix"><a href="//www.bilibili.com/video/BV1ME411Y71o?from=search" title="【尚硅谷】Golang入门到实战教程丨一套精通GO语言" target="_blank" class="img-anchor"><div class="img"><div class="lazy-img"><img alt="" src=""></div><span class="so-imgTag_rb">117:16:23</span><div class="watch-later-trigger watch-later"></div><span class="mask-video"></span></div><!----></a><div class="info"><div class="headline clearfix"><!----><!----><span class="type hide">校园学习</span><a title="【尚硅谷】Golang入门到实战教程丨一套精通GO语言" href="//www.bilibili.com/video/BV1ME411Y71o?from=search" target="_blank" class="title">【尚硅谷】<em class="keyword">Golang</em>入门到实战教程丨一套精通GO<em class="keyword">语言</em></a></div><div class="des hide">
      制作不易,大家记得点个关注,一键三连呀【点赞、投币、收藏】感谢支持~
尚硅谷菁英师资整合业界资源,历时一年,打磨出专注于区块链技术的GO语言视频教程。教程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底...
    </div><div class="tags"><span title="观看" class="so-icon watch-num"><i class="icon-playtime"></i>
        122.2万
      </span><span title="弹幕" class="so-icon hide"><i class="icon-subtitle"></i>
        3.9万
      </span><span title="上传时间" class="so-icon time"><i class="icon-date"></i>
        2019-10-27
        
        ……

我们还能在

Get请求中添加请求头

我们可以这样

// 建一个客户端
client := http.Client{}

// new一个请求
request, err := http.NewRequest("GET", url字符串)

// 在请求的头部添加键值对信息
request.Header.Add(key,value)

// 我们设置完后可以这样发送
respronse, err := client.Do(request)

// 此时就得到了response

如果请求到的响应时json数据,那么我们还可以通过json包里的api将json数据转成结构体


Post

我们除了有Get请求,我们还能有Post请求

我们发送Post请求有两种方式

我们的Post请求肯定是要提交请求体的

第一种

发送Post表单请求

// url路径
urlPath := "你需要的url路径"

// 创建一个Values结构体
values := url.Values{}

// 设置values
values.Set("key","value")

// 发送Post表单请求
response, err := http.PostForm(urlPath, values)

// 此时拿到response
……

第二种

发送普通Post请求


func testPost() {
   urlPath := "hello"

   // 创建一个带有参数的Values结构体
   values := url.Values{
      "key", {"value"},
   }

   // 防止中文需要执行
   encode := values.Encode()

   // 使用strings包新建一个Reader
   reader := strings.NewReader(encode)

   // 发送Post
   // 第二个参数为内容类型,是string
   // 调用者在完成读取后应关闭 resp.Body。
   // 如果提供的主体是 io.Closer,则在请求后关闭
   // 第三个参数为请求体,类型为io.Reader
   response, err := http.Post(urlPath, "text/html", reader)
   
   // 此时拿到response
   ……

}


除了这两种,还可以发送json数据的post请求

也是调用Post()

将第二个参数改成 "application/json"

将第三个Reader参数改成json数据所生成的Reader


Client自定义请求

我们在Get请求中的添加请求头部分提到了一次

我们看到Client的源码中

type Client struct {
  
   Transport RoundTripper

   CheckRedirect func(req *Request, via []*Request) error
   
   Jar CookieJar

   Timeout time.Duration
}

一共可以有四种参数

分别是

传输指定发出单个 HTTP 请求的机制。如果为零,则使用 DefaultTransport

Transport RoundTripper

CheckRedirect 指定处理重定向的策略。如果 CheckRedirect 不为零,则客户端会在执行 HTTP 重定向之前调用它

CheckRedirect func(req *Request, via []*Request) error

Jar 指定 cookie jar。

Jar 用于将相关 cookie 插入到每个出站请求中,并使用每个入站响应的 cookie 值进行更新

Jar CookieJar

设置超时

Timeout time.Duration

然后通过New一个Request来进行请求

// 建一个客户端
client := http.Client{}

// new一个请求
request, err := http.NewRequest("GET", url字符串)

// 这样发送
respronse, err := client.Do(request)

// 此时就得到了response

……

这样,我们就能做到通过使用http标准库中的api来进行Golang的客户端功能

😎😎😎又是我,我还是小小分割线

都用心看到这里了,那就求个赞吧😘

🥳🥳🥳如果小伙伴有其他的小知识,一定不要忘了在评论区讨论哟,多多讨论,生态才会越来越好