注册 登录

清河洛

Go的标准库net/http客户端简单使用

qingheluo2024-12-27清河洛168
Go的标准库net/http提供的完整的http服务端和客户端的实现,此篇文章仅记录客户端常用相关功能的使用从Go1.6开始,http包在使用HTTPS时对HTTP/2协议默认支持包级函数 CanonicalHeaderKey(s string) string 返回标头中键的规范格式 将第一个字母和连字符"-"后面的任何字母转换为大写,其余部分将转换为小写 如果包含空格或无效的标头字段字节,则不进行任何修改返回 DetectContentType(data []byte) string 获取给定数据的Content-Type 最多读取分析前 512 字节的数...

Go的标准库net/http提供的完整的http服务端和客户端的实现,此篇文章仅记录客户端常用相关功能的使用

从Go1.6开始,http包在使用HTTPS时对HTTP/2协议默认支持

包级函数

CanonicalHeaderKey(s string) string  返回标头中键的规范格式
    将第一个字母和连字符"-"后面的任何字母转换为大写,其余部分将转换为小写
    如果包含空格或无效的标头字段字节,则不进行任何修改返回

DetectContentType(data []byte) string  获取给定数据的Content-Type
    最多读取分析前 512 字节的数据
    如果无法确定具体的 MIME 类型,则返回"application/octet-stream"

ParseTime(text string) (t time.Time, err error)  解析头中的时间字符串

ProxyFromEnvironment(req *Request) (*url.URL, error)
    获取指定请求使用的代理URL
    会读取Transport设置、本地环境变量HTTP_PROXY、HTTPS_PROXY等
    如果最终分析结果是不使用代理,*url.URL返回nil

ProxyURL(fixedURL *url.URL) func(*Request) (*url.URL, error)
    返回代理函数用于设置Transport的Proxy字段

StatusText(code int) string  返回状态码对应的文本,状态码未知返回空字符串

Client

表示一个HTTP客户端

包级变量DefaultClient表示默认客户端:var DefaultClient = &Client{}

type Client struct {
    Transport RoundTripper
    CheckRedirect func(req *Request, via []*Request) error
    Jar CookieJar
    Timeout time.Duration
}

Transport       表示客户端获取指定请求响应的接口实现
    RoundTripper是一个接口,仅含一个方法:RoundTrip(*Request) (*Response, error)
    表示执行单个HTTP事务,获取指定请求的响应
    一个RoundTripper必须对多个goroutine并发安全
CheckRedirect   处理重定向的策略
    如果为nil,将使用默认策略,在连续10个重定向后停止
    如果不为nil,客户端在执行HTTP重定向之前调用它
    req和via是即将发送的请求和已经发出的请求,越早的请求在via中越靠前
    如果返回错误,将终端后续请求并返回之前的Response(其Body已关闭)和CheckRedirect的错误
Jar             指定每次请求发送的cookie
    cookie会自动使用响应的cookie值进行更新
    如果为nil,只有在Request中明确设置Cookie时才会发送Cookie
Timeout         客户端超时时间,从请求发送后开始计时,零值表示不限制

Client常用方法

CloseIdleConnections()    关闭所有空闲连接
Do(req *Request) (*Response, error)   发送请求并返回响应

以下方法使用指定的方法发送请求,无法对请求进行更精细的设置,如自定义请求头,设置超时等
Get(url string) (resp *Response, err error)
Head(url string) (resp *Response, err error)
Post(url, contentType string, body io.Reader) (resp *Response, err error)
PostForm(url string, data url.Values) (resp *Response, err error)
    请求头的Content-Type自动设置为application/x-www-form-urlencoded

type Transport{}

Transport是RoundTripper的一种实现,可以设置客户端的连接属性,如代理、TSL、闲置连接数,数据压缩等,常用字段有

Proxy func(*Request) (*url.URL, error)
    获取代理用于连接
    当返回了非nil的错误值,请求的执行就会中断并返回该错误
    字段设为nil或函数返回nil,表示不使用代理
    如果返回URL中不含有协议,默认使用http协议

OnProxyConnectResponse func(ctx context.Context, proxyURL *url.URL, connectReq *Request, connectRes *Response) error
    在使用代理发送请求并接收到代理返回的响应时运行该函数
    会在自动检查状态码之前运行
    如果该函数返回错误,请求将失败并返回该错误

TLSHandshakeTimeout time.Duration
    指定等待TLS握手完成的超时时间,零值表示不设置超时

DisableKeepAlives bool
    是否禁止不同HTTP请求之间TCP连接重用
    如果为true只会将与服务器的连接用于单个HTTP请求
    默认情况下,会缓存连接以供将来重复使用
    在访问了多个主机时可能会留下许多打开的连接,这些连接称之为空闲链接

DisableCompression bool
    是否禁止在请求头中没有Accept-Encoding时自动添加"Accept-Encoding: gzip"
    如果是自动添加的Accept-Encoding请求头,会主动解压缩回复的主体
    如果用户显式的设置Accept-Encoding请求头,不会主动解压缩

MaxIdleConns int
    所有主机的最大空闲连接数,零值表示不限制

MaxIdleConnsPerHost int
    每个主机的最大空闲连接数,默认2

MaxConnsPerHost int
    每个主机的最大连接数,包括活动和空闲连接,零值表示不限制

IdleConnTimeout time.Duration
    空闲连接的最大空闲时间,超时将断开连接,零值表示不限制

ResponseHeaderTimeout time.Duration
    指定在请求发送完毕(包括主体)之后等待服务端回复头域的最大时间
    该时间不包括获取回复主体的时间
    零值表示不设置超时

ExpectContinueTimeout time.Duration
    当请求头中包含"Expect: 100-continue"时,请求头发送完毕之后等待服务端回复头域的最大时间
    零值表示不设置超时
    当包含"Expect: 100-continue"请求头时,会先发送整个请求头给服务器
    服务器通过"Content-Length"或其他请求头判断是否接受此次请求
    服务器返回100时表示接受此次请求,返回417时表示拒绝此次请求
    客户端根据返回码来决定是否发送body

ProxyConnectHeader Header
    设置在CONNECT请求时发送给代理的请求头

GetProxyConnectHeader func(ctx context.Context, proxyURL *url.URL, target string) (Header, error)
    设置在CONNECT请求时发送给代理的请求头
    如果返回错误不为nil,改次请求将失败并返回该错误
    返回(nil,nil)表示不添加标头
    如果该字段非空则忽略ProxyConnectHeader字段

MaxResponseHeaderBytes int64
    允许服务器响应头的最大字节数,零值表示不限制

WriteBufferSize int
ReadBufferSize int
    传输和读取数据时的缓冲区字节大小,默认均为4096(4KB)
}

Transport的常用方法

Clone() *Transport      深层复制一个副本
CloseIdleConnections()  关闭所有空闲连接

type Request{}

表示服务器接收或客户端发送的 HTTP 请求

Method string      请求方法,支持的有"GET"(默认),"POST","HEAD","PUT",
                   "PATCH","DELETE","CONNECT","OPTIONS","TRACE"
URL *url.URL        请求地址
Proto      string   协议版本,如"HTTP/1.0"
ProtoMajor int      协议主版本号,如1
ProtoMinor int      协议次版本号,如0
Header Header       请求头
Body io.ReadCloser  请求主体,
                    HTTP客户端负责在传输完毕后调用Close()方法
                    包级变量NoBody表示没有主体,Read 始终返回 EOF,Close 始终返回 nil
                        var NoBody = noBody{}
                    设为nil也表示没有主体,等同于设置为NoBody
ContentLength int64 可从Body中读取的字节数,-1表示未知
Close bool          请求完成(读取相应)后是否关闭连接
                    功能和Transport.DisableKeepAlives相同
Host string         设置Host请求头,默认使用URL中的Host字段

创建Request

NewRequestWithContext(ctx context.Context, method, url string, body io.Reader) (*Request, error)
    使用指定上下文、方法、url及body创建一个Request

NewRequest(method, url string, body io.Reader) (*Request, error)
    使用context.Background上下文创建一个Request

WithContext(ctx context.Context) *Request
    返回浅表副本,更改其上下文为ctx
    提供的ctx必须为非nil

Request常用方法

AddCookie(c *Cookie)      追加加cookie,不会覆盖已存在的值
SetBasicAuth(username, password string)
    设置Authorization请求头用于基本身份验证
BasicAuth() (username, password string, ok bool)
Context() context.Context  获取请求中的上下文
Cookie(name string) (*Cookie, error)  获取指定的cookie,如果有多个返回第一个
CookiesNamed(name string) []*Cookie   获取指定的cookie
Cookies() []*Cookie
UserAgent() string

type Response{}

表示来自 HTTP 请求的响应

Status     string   返回状态码及信息,如"200 OK"
StatusCode int      返回状态码
Proto      string   协议版本,如"HTTP/1.0"
ProtoMajor int      协议主版本
ProtoMinor int      协议次版本
Header Header       响应头
Body io.ReadCloser  相应主体
    当读取时会按需流式传输
    如果网络连接失败或服务器终止响应,读取时返回错误
ContentLength int64 主体字节大小,-1表示未知
Close bool          是否建议在读取Body后关闭连接
                    仅为服务器建议,并不会主动在读取body后关闭连接
Uncompressed bool   响应是否是以压缩形式发送,客户端应该执行解压缩操作
    当为true时,从Body读取时实际读取到的是解压缩后的内容而非服务器传输的原始值
    此时ContentLength自动设为-1,并删除"Content-Length"和"Content-Encoding"
Request *Request    返回获取该相应的Body字段为空的请求

创建Response

Get(url string) (resp *Response, err error)
Head(url string) (resp *Response, err error)
Post(url, contentType string, body io.Reader) (resp *Response, err error)
PostForm(url string, data url.Values) (resp *Response, err error)

Response常用方法

Cookies() []*Cookie   解析并返回在Set-Cookie标头中设置的Cookie
Location() (*url.URL, error)  返回Location标头(重定向)值

type Cookie

表示在HTTP请求的Cookie标头中发送的Cookie或HTTP响应的Set-Cookie标头

Name       string
Value      string
Path       string     只有当请求路径的前缀匹配该值时,Cookie才会被发送
Domain     string     如果该值为主域名,则匹配所有子域名
Expires    time.Time  过期时间
RawExpires string     原始过期时间字符串,通常为Set-Cookie头中的原始值

MaxAge      int       生效时长(秒)
    为0表示不设置该值,会在回话结束时删除
    小于0表示立即删除
    会覆盖Expires字段的设置
Secure      bool      是否仅通过HTTPS传输时才发送该Cookie
HttpOnly    bool      是否仅允许通HTTP协议访问该Cookie
    为true时JS无法通过document.cookie访问该Cookie,从而提高安全性
SameSite    SameSite  用于限制跨站请求的行为,值为常量
    type SameSite int
    SameSiteDefaultMode 1,默认,表示未设置SameSite属性
    SameSiteLaxMode     2,允许部分跨站请求(如 GET 请求)。
    SameSiteStrictMode  3,完全禁止跨站请求使用该 Cookie。
    SameSiteNoneMode    4,允许跨站请求,但必须设置Secure属性
Partitioned bool       是否开启上下文隔离
    开启后不同的上下文中,Cookie会被隔离无法共享,即使是同一个域名
    这种机制需要浏览器支持,并且通常需要配合SameSite=None 和Secure属性使用
Raw         string     原始未解析的Cookie字符串
Unparsed    []string   未解析的Slice,存储解析时无法识别的字段

创建Cookie

ParseCookie(line string) ([]*Cookie, error)   解析请求Cookie标头

ParseSetCookie(line string) (*Cookie, error)  解析Set-Cookie标头

Cookie常用方法

String() string
Valid() error    改Cookie是否有效

type CookieJar

管理HTTP请求中Cookie的存储和使用,对多个goroutine并发使用是安全的

type CookieJar interface {
    SetCookies(u *url.URL, cookies []*Cookie)
    Cookies(u *url.URL) []*Cookie
}

在包"net/http/cookiejar"中实现了CookieJar接口

New(o *Options) (*Jar, error)

type Options struct {
    PublicSuffixList PublicSuffixList
}
PublicSuffixList是公共后缀列表,用于决定HTTP服务端是否能给某域名设置cookie
nil值合法的,但是不安全,允许HTTP服务端跨域名设置cookie

"golang.org/x/net/publicsuffix"包的publicsuffix.List可用于设置该字段

jar,err := cookiejar.New(&cookiejar.Options{
    PublicSuffixList: publicsuffix.List,
})

type Header

表示HTTP头中的键值对:type Header map[string][]string

在Header中,key不区分大小写

Header常用方法

Set(key, value string) 清空指定key对应的值并设置为包含一个value元素的Slice
Add(key, value string) 将value追加到指定key对应的Slice中
Clone() Header         获取一个副本
Del(key string)        删除指定头
Get(key string) string 获取指定key对应的Slice中的第一个值
Values(key string) []string  获取指定key对应的值


网址导航