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对应的值