前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Go 语言网络编程系列(三)—— HTTP 编程篇:客户端如何发起请求

Go 语言网络编程系列(三)—— HTTP 编程篇:客户端如何发起请求

作者头像
学院君
发布2019-10-31 14:42:45
2.5K0
发布2019-10-31 14:42:45
举报
文章被收录于专栏:学院君的专栏学院君的专栏

通过前面介绍的 net.Dialnet.DialTimeout 函数来访问基于 HTTP 协议的网络服务是完全没有问题的,因为 HTTP 协议是基于 TCP/IP 协议栈的。不过没问题不代表很方便,如果通过 net.Dial 函数进行 HTTP 编程,HTTP 状态码、报文头部和实体部分处理起来是相当繁琐的(关于 HTTP 协议的更多细节可以阅读网络协议里的应用层协议来详细了解),因此 Go 语言标准库内置了 net/http 包来涵盖 HTTP 客户端和服务端的具体实现,通过 net/http 包我们可以更方便快捷地编写 HTTP 客户端和服务端程序。

学院君注:这里的 HTTP 客户端编程类似 PHP 里面使用 curl 或者 Guzzle 扩展包发起 HTTP 请求,HTTP 服务端编程类似实现 PHP 里面的 PHP-FPM 或者 Swoole HTTP 服务器对客户端请求进行响应。

首先我们来看 HTTP 客户端编程。

1、http.Client

net/http 包提供了最简洁的 HTTP 客户端实现,无需借助第三方网络通信库(比如 libcurl)就可以直接使用最常见的 GETPOST 方式发起 HTTP 请求。

具体来说,我们可以通过 net/http 包里面的 Client 类提供的如下方法发起 HTTP 请求:

func (c *Client) Do(req *Request) (*Response, error)func (c *Client) Get(url string) (resp *Response, err error)func (c *Client) Head(url string) (resp *Response, err error)func (c *Client) Post(url, contentType string, body io.Reader) (resp *Response, err error)func (c *Client) PostForm(url string, data url.Values) (resp *Response, err error)

下面学院君简单介绍下这几个方法的使用。

2、http.Get

示例代码

要发起一个 GET 请求,只需调用 http.Get() 方法并传入请求 URL 即可,示例代码如下:

resp, err := http.Get("https://xueyuanjun.com") if err != nil {    // 处理错误 ...    return }
defer resp.Body.Close() io.Copy(os.Stdout, resp.Body)

上面这段代码用于对学院君首页发起请求,并将其网页内容打印到标准输出流中。

底层调用

其实通过 http.Get 发起请求时,默认调用的是上述 http.Client 缺省对象上的 Get 方法:

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

DefaultClient 默认指向的正是 http.Client 对象实例:

var DefaultClient = &Client{}

它是 net/http 包公开属性,当我们在 http 上调用 GetPostPostFormHead 方法时,最终调用的都是该对象上的对应方法。

返回值

回到 http.Get() 方法本身,该方法返回值有两个,第一个是响应对象,第二个是 error 对象,如果请求过程中出现错误,则 error 对象不为空,否则,可以通过响应对象获取状态码、响应头、响应实体等信息,响应对象所属的类是 http.Response,你可以查看 API 文档或者源码了解该类型的具体信息,一般我们可以通过 resp.Body 获取响应实体,通过 resp.Header 获取响应头,通过 resp.StatusCode 获取响应状态码。

获取响应成功后记得调用 resp.Body 上的 Close 方法结束网络请求释放资源。

3、http.Post

要以 POST 的方式发送数据,也很简单,只需调用 http.Post() 方法并依次传递下面这 3 个参数即可:

  • 请求目标的 URL
  • POST 请求数据的资源类型(MIME Type)
  • 数据的比特流([]byte 形式)

下面的示例代码演示了如何上传用户头像:

resp, err := http.Post("https://xueyuanjun.com/avatar", "image/jpeg", &imageDataBuf) if err != nil {    // 处理错误    return }
if resp.StatusCode != http.StatusOK {     // 处理错误     return }
// ...

底层实现及返回值和 http.Get 一样。

4、http.PostForm

http.PostForm() 方法实现了标准编码格式为 application/x-www-form-urlencoded 的 POST 表单提交。

下面的示例代码模拟 HTML 登录表单提交:

resp, err := http.PostForm("https://xueyuanjun.com/login", url.Values{"name":{"学院君"}, "password": {"test-passwd"}}) 
if err != nil {    // 处理错误    return } 
if resp.StatusCode != http.StatusOK {     // 处理错误     return } 
// ...

注意,POST 请求参数需要通过 url.Values 方法进行编码和封装。

底层实现及返回值和 http.Get 一样。

5、http.Head

HTTP 的 Head 请求表示只请求目标 URL 的响应头信息,不返回响应实体。我们可以通过 http.Head() 方法发起 Head 请求,该方法和 http.Get() 方法一样,只需传入目标 URL 参数即可。

下面的示例代码用于请求学院君首页的 HTTP 响应头信息:

resp, err := http.Head("https://xueyuanjun.com")if err != nil {    fmt.Println("Request Failed: ", err.Error())    return}
defer resp.Body.Close()// 打印头信息for  key, value := range resp.Header  {    fmt.Println(key, ":", value)}

通过 http.Head() 方法返回的响应实体 resp.Body 值为空。 底层实现及返回值和 http.Get 一样。

6、(*http.Client).Do

最后,我们来看一下 http.Client 类的 Do 方法。

在多数情况下,http.Gethttp.Posthttp.PostForm 就可以满足需求,但是如果我们发起的 HTTP 请求需要设置更多的自定义请求头信息,比如:

  • 设置自定义的 User-Agent,而不是默认的 Go http package
  • 传递 Cookie 信息;
  • 发起其它方式的 HTTP 请求,比如 PUTPATCHDELETE 等。

此时可以通过 http.Client 类提供的 Do() 方法来实现,使用该方法时,就不再是通过缺省的 DefaultClient 对象调用 http.Client 类中的方法了,而是需要我们手动实例化 Client 对象并传入添加了自定义请求头信息的请求对象来发起 HTTP 请求:

// 初始化客户端请求对象req, err := http.NewRequest("GET", "https://xueyuanjun.com", nil)if err != nil {    // ... 出错处理    return}// 添加自定义请求头req.Header.Add("Custom-Header", "Custom-Value")// ... 其它请求头配置client := &http.Client{    // ... 设置客户端属性}resp, err := client.Do(req)if err != nil {    // ... 出错处理    return}
defer resp.Body.Close()io.Copy(os.Stdout, resp.Body)

用于初始化请求对象的 http.NewRequest 方法需要传入三个参数,第一个是请求方法,第二个是目标 URL,第三个是请求实体,只有 POST、PUT、DELETE 之类的请求才需要设置请求实体,对于 HEAD、GET 而言,传入 nil 即可。

http.NewRequest 方法返回的第一个值就是请求对象实例 req,该实例所属的类是 http.Request,你可以调用该类上的公开方法和属性对请求对象进行自定义配置,比如请求方法、URL、请求头等。

设置完成后,就可以将请求对象传入 client.Do() 方法发起 HTTP 请求,之后的操作和前面四个基本方法一样。

更多使用细节我们会在后续教程单独介绍,比如 Cookie 如何设置、文件如何上传和下载、请求/响应超时如何处理等,这里只是简单介绍这几个基本 HTTP 请求方法的使用。

Tips:想要阅读全部 Go 语言从入门到精通教程,请点击左下角“阅读原文”链接。

https://xueyuanjun.com/post/20989

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-10-25,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 极客书房 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1、http.Client
  • 2、http.Get
    • 示例代码
      • 底层调用
        • 返回值
        • 3、http.Post
        • 4、http.PostForm
        • 5、http.Head
        • 6、(*http.Client).Do
        相关产品与服务
        命令行工具
        腾讯云命令行工具 TCCLI 是管理腾讯云资源的统一工具。使用腾讯云命令行工具,您可以快速调用腾讯云 API 来管理您的腾讯云资源。此外,您还可以基于腾讯云的命令行工具来做自动化和脚本处理,以更多样的方式进行组合和重用。
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档