Gorequest指南

gorequest为 golang 程序提供了极为简便的方式发起 HTTP 请求。网上关于这个库的中文教程不多,因此把官方的 README 文件翻译过来,结合自己的一些使用经验,希望能为各位 Gopher 提供一些帮助。

GopherGoRequest

特性

  • 支持发送Get/Post/Put/Head/Delete/Patch/Options 请求
  • 建议的请求头设置
  • JSON 支持:以 JSON 格式字符串作为函数参数的方式简化传输 JSON 的步骤。
  • 分段支持:分段请求(Multipart Request)的方式发送数据或传输文件
  • 代理:支援通过代理的方式发送请求。
  • Timeout:为请求设置时间限制
  • TLS(传输层安全协议)相关设定。
    > TLSClientConfig - taking control over tls where at least you can disable security check for https
  • 重定向策略
  • Cookie:为请求添加 cookie
  • CookieJar - automatic in-memory cookiejar
  • 基本的权限认证。

使用

1
$ go get github.com/parnurzeal/gorequest

使用 GoRequest 的理由?

通过 GoRequest 可以使工作变得更简单,使可以发起 HTTP 请求这件事更加优雅而充满乐趣。

不使用本库发起简单 GET 请求:

1
resp, err := http.Get("http://example.com/")

1、定义request请求

使用 GoRequest

1
2
request := gorequest.New()
resp, body, errs := request.Get("http://example.com/").End()

如果你不想重用request,也可以写成下面这样

1
resp, body, errs := gorequest.New().Get("http://example.com/").End()

2、设置Header

如果你需要设定 HTTP 头,设定重定向策略等,使用标准库会瞬间使事情变得异常复杂,在发起仅仅一个 GET 请求的过程,你就需要一个 Client,通过一系列不同的命令来设定 HTTP 头(HTTP Headers)。

1
2
3
4
5
6
7
8
client := &http.Client{
CheckRedirect: redirectPolicyFunc,
}

req, err := http.NewRequest("GET", "http://example.com", nil)

req.Header.Add("If-None-Match", `W/"wyzzy"`)
resp, err := client.Do(req)

现在,你有更加美妙的方式来完成这件事

1
2
3
4
5
6
request := gorequest.New()
resp, body, errs := request.Get("http://example.com").
RedirectPolicy(redirectPolicyFunc).
Set("If-None-Match", `W/"wyzzy"`).
Set("Content-Type", "application/json").
End()

发起 DELETE, HEAD, POST, PUT, PATCH 请求的过程和发起 GET 请求类似。

1
2
3
4
5
6
request := gorequest.New()
resp, body, errs := request.Post("http://example.com").End()
// PUT -> request.Put("http://example.com").End()
// DELETE -> request.Delete("http://example.com").End()
// HEAD -> request.Head("http://example.com").End()
// ANYTHING -> request.CustomMethod("TRACE", "http://example.com").End()

3、处理Json数据

用标准库发起 JSON POST ,你需要先将 map 或者 struct格式的数据包装(Marshal)成 JSON 格式的数据,将头参数设定为’application/json’(必要时还要设定其他头),然后要新建一个http.CLient变量。经过这一系列的步骤,你的代码变得冗长而难以维护

1
2
3
4
5
6
7
8
9
10
11
m := map[string]interface{}{
"name": "backy",
"species": "dog",
}
mJson, _ := json.Marshal(m)
contentReader := bytes.NewReader(mJson)
req, _ := http.NewRequest("POST", "http://example.com", contentReader)
req.Header.Set("Content-Type", "application/json")
req.Header.Set("Notes","GoRequest is coming!")
client := &http.Client{}
resp, _ := client.Do(req)

至于 GoRequest, JSON 支持是必须的,所以,用这个库你只需要一行代码完成所有工作

1
2
3
4
5
request := gorequest.New()
resp, body, errs := request.Post("http://example.com").
Set("Notes","gorequst is coming!").
Send(`{"name":"backy", "species":"dog"}`). // 提交的josn数据
End()

另外,它同样支持结构体类型。所以,你可以在你的请求中发送不同的数据类型(So, you can have a fun Mix & Match sending the different data types for your request)。

1
2
3
4
5
6
7
8
9
10
type BrowserVersionSupport struct {
Chrome string
Firefox string
}
ver := BrowserVersionSupport{ Chrome: "37.0.2041.6", Firefox: "30.0" }
request := gorequest.New()
resp, body, errs := request.Post("http://version.com/update").
Send(ver).
Send(`{"Safari":"5.1.10"}`).
End()

不仅支持 Send(),还支持 Query()

4、回调(Callback)

此外,GoRequest 支持回调函数,这让你可以更加灵活的使用这个库。
下面是回调函数的一个例子

1
2
3
4
func printStatus(resp gorequest.Response, body string, errs []error){
fmt.Println(resp.Status)
}
gorequest.New().Get("http://example.com").End(printStatus)

5、Multipart/Form-Data

你可以将请求的内容类型设定为multipart来以multipart/form-data的方式发送所有数据。这个特性可以帮助你发送多个文件。
下面是一个例子

1
2
3
4
gorequest.New().Post("http://example.com/").
Type("multipart").
Send(`{"query1":"test"}`).
End()

如果感兴趣可以在文档中查看SendFile函数部分获取更多。

6、代理(Proxy)

需要使用代理的时候,可以用 GoRequest Proxy Func 很好的处理。

1
2
3
4
request := gorequest.New().Proxy("http://proxy:999")
resp, body, errs := request.Get("http://example-proxy.com").End()
// 若要在没有代理的情况下重用同一客户端,请使用空字符串
resp, body, errs = request.Proxy("").Get("http://example-no-proxy.com").End()

7、基本认证

添加基本的认证头信息

1
2
request := gorequest.New().SetBasicAuth("username", "password")
resp, body, errs := request.Get("http://example-proxy.com").End()

8、超时处理(Timeout)

time 库结合可以设置成任何的时间限制。

1
2
request := gorequest.New().Timeout(2*time.Millisecond)
resp, body, errs:= request.Get("http://example.com").End()

Timeout 函数同时设定了连接和 IO 的时间限制。

9、以字节方式处理返回体(EndBytes)

当希望正文为字节时,我们现在可以使用 EndBytes。

回调的工作方式与 with 相同End,除了使用字节数组而不是字符串。

1
resp, bodyBytes, errs := gorequest.New().Get("http://example.com/").EndBytes()

10、以结构体的方式处理返回体

假设 URL http://example.com/ 的返回体 {"hey":"you"}

1
2
3
4
5
6
7
heyYou struct {
Hey string `json:"hey"`
}

var heyYou heyYou

resp, _, errs := gorequest.New().Get("http://example.com/").EndStruct(&heyYou)

11、连续重复请求(Retry)

假设你在得到 BadRequest 或服务器内部错误(InternalServerError)时进行连续三次,间隔五秒的连接尝试

1
2
3
4
request := gorequest.New()
resp, body, errs := request.Get("http://example.com/").
Retry(3, 5 * time.Second, http.StatusBadRequest, http.StatusInternalServerError).
End()

12、处理重定向

可以使用 RedirectPolicy 处理重定向,其行为类似于 net/http 客户端的CheckRedirect 函数。只需指定一个函数,该函数接受即将发出的请求和先前请求的一部分,按最早的顺序排列。当此函数返回错误时,不会发出请求。

例如仅重定向到 https 端点:

1
2
3
4
5
6
7
8
request := gorequest.New()
resp, body, errs := request.Get("http://example.com/").
RedirectPolicy(func(req Request, via []*Request) error {
if req.URL.Scheme != "https" {
return http.ErrUseLastResponse
}
}).
End()

13、跳过ssl证书检查

想跳过https的证书校验时用下面示例

1
2
3
resp, body, errs := gorequest.New().TLSClientConfig(&tls.Config{ InsecureSkipVerify: true}).
Get("https://disable-security-check.com").
End()