本文来自网易云社区
作者:盛国存
Go语言有很多的标准库,http库是最重要的之一,它对Http的封装也是非常完善的,之前我们有演示过服务端的一些基础使用,下面我们介绍一些客户端相关的使用
package main
import (
"net/http"
"net/http/httputil"
"fmt"
)
func main() {
response, err := http.Get("https://www.shengguocun.com")
if err != nil{
panic(err)
}
defer response.Body.Close()
ss, err := httputil.DumpResponse(response, true)
if err != nil {
panic(err)
}
fmt.Printf("%s \n", ss)
}
这里就把完整的头信息以及html的部分打印出来了。比如在我们现实的情境中,我们会根据UA做一些反作弊的策略,以及是否需要重定向到 M 端等等。这里的 http.Client
就能实现。
请求头信息直接通过 request.Header.Add
添加就可以了
package main
import (
"net/http"
"net/http/httputil"
"fmt"
)
func main() {
request, err := http.NewRequest(http.MethodGet,"https://www.shengguocun.com", nil)
request.Header.Add("User-Agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.139 Safari/537.36")
response, err := http.DefaultClient.Do(request)
if err != nil{
panic(err)
}
defer response.Body.Close()
ss, err := httputil.DumpResponse(response, true)
if err != nil {
panic(err)
}
fmt.Printf("%s \n", ss)
}
上面我们都用的是 DefaultClient ,我们也可以自己创建 client, 首先我们先看一下 Client 内部都有些什么
查看源码我们发现有一个 CheckRedirect
,我们发现这是一个检查重定向的函数。那我们就用它做一下演示
package main
import (
"net/http"
"net/http/httputil"
"fmt"
)
func main() {
request, err := http.NewRequest(http.MethodGet,"https://jim-sheng.github.io", nil)
request.Header.Add("User-Agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.139 Safari/537.36")
client := http.Client{
CheckRedirect: func(req *http.Request, via []*http.Request) error {
fmt.Println("重定向地址:", req)
return nil
},
}
response, err := client.Do(request)
if err != nil{
panic(err)
}
defer response.Body.Close()
ss, err := httputil.DumpResponse(response, true)
if err != nil {
panic(err)
}
fmt.Printf("%s \n", ss)
}
输出结果(部分)
重定向地址: &{GET https://www.shengguocun.com/ 0 0 map[User-Agent:[Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.139 Safari/537.36] Referer:[https://jim-sheng.github.io]] <nil> <nil> 0 [] false map[] map[] <nil> map[] <nil> <nil> 0xc42012c090 <nil>}
HTTP/2.0 200 OK
Accept-Ranges: bytes
Access-Control-Allow-Origin: *
我们可以看到具体的重定向的地址 https://www.shengguocun.com/ ,其它的
// Transport specifies the mechanism by which individual
// HTTP requests are made.
// If nil, DefaultTransport is used.
Transport RoundTripper
主要用于代理
// Jar specifies the cookie jar.
//
// The Jar is used to insert relevant cookies into every
// outbound Request and is updated with the cookie values
// of every inbound Response. The Jar is consulted for every
// redirect that the Client follows.
//
// If Jar is nil, cookies are only sent if they are explicitly
// set on the Request.
Jar CookieJar
主要用于模拟登录用的
// Timeout specifies a time limit for requests made by this
// Client. The timeout includes connection time, any
// redirects, and reading the response body. The timer remains
// running after Get, Head, Post, or Do return and will
// interrupt reading of the Response.Body.
//
// A Timeout of zero means no timeout.
//
// The Client cancels requests to the underlying Transport
// using the Request.Cancel mechanism. Requests passed
// to Client.Do may still set Request.Cancel; both will
// cancel the request.
//
// For compatibility, the Client will also use the deprecated
// CancelRequest method on Transport if found. New
// RoundTripper implementations should use Request.Cancel
// instead of implementing CancelRequest.
Timeout time.Duration
主要设置超时的
还是使用之前的代码
package main
import (
"net/http"
"os"
"io/ioutil"
_ "net/http/pprof"
)
type appHandler func(writer http.ResponseWriter, request *http.Request) error
func errWrapper(handler appHandler) func(http.ResponseWriter, *http.Request) {
return func(writer http.ResponseWriter, request *http.Request) {
err := handler(writer, request)
if err != nil {
switch {
case os.IsNotExist(err):
http.Error(writer, http.StatusText(http.StatusNotFound), http.StatusNotFound)
}
}
}
}
func main() {
http.HandleFunc("/list/",
errWrapper(func(writer http.ResponseWriter, request *http.Request) error {
path := request.URL.Path[len("/list/"):]
file, err := os.Open(path)
if err != nil {
return err
}
defer file.Close()
all, err := ioutil.ReadAll(file)
if err != nil {
return err
}
writer.Write(all)
return nil
}))
err := http.ListenAndServe(":2872", nil)
if err != nil {
panic(err)
}
}
还是一样的代码,只不过import多了一个 import _ "net/http/pprof"
, 为什么会多一个下划线呢?因为代码没有使用到,会报错,加一个下划线就可以了。重启代码,我们就可以访问 http://localhost:2872/debug/pprof/ 了
我们可以查看 pprof 的源码,继续查看它的其他的使用方式
// Or to look at a 30-second CPU profile:
//
// go tool pprof http://localhost:6060/debug/pprof/profile
比如这一段,我们可以查看30秒的CPU的使用情况。可以终端敲下该命令(替换成自己的监听的端口),获取出结果后敲下 web 命令就可以看下具体的代码哪些地方需要优化。其他的使用使用方式就不一一罗列了,有兴趣可以继续查阅。
其它的标准库就不过多罗列了, https://studygolang.com/pkgdoc 上面的中文版的文档已经非常详细了 。
Go语言给我们展现了不一样的世界观,没有类、继承、多态、重载,没有构造函数,没有断言,没有try/catch等等;上面是在学习Go语言的过程中,记录下来的笔记;也可能有部分地方存在偏颇,还望指点~~~
相关阅读:A Bite of GoLang (1)
网易云免费体验馆,0成本体验20+款云产品!
更多网易研发、产品、运营经验分享请访问网易云社区。