Go语言
文章目录
17. HTTP编程(上)
如何使用Go语言创建HTTP服务器和客户端,使用Go语言开发Web服务,让开发者不需要进行各种繁杂的性能优化就可以很轻松地开发出一个高性能的Web服务。
17.1 HTTP简介
17.1.1 HTTP协议
HTTP,即超文本传输协议(HyperText Transfer Protocol),是互联网上应用最为广泛的一种网络协议。它详细规定了浏览器和万维网服务器之间的相互通信规则,所有的WWW文件都必须遵守这个标准。设计HTTP最初的目的是为了提供一种发布和接收HTML页面的方法。
HTML叫超文本标记语言(HyperText Markup Language),是标准通用标记语言下的一个应用。HTML不是一种编程语言,而是一种标记语言(markup language),是网页制作所必备的。“超文本”就是指页面内可以包含图片、链接,甚至音乐、程序等非文字元素。超文本标记语言(或超文本标签语言)的结构包括“头”部分和“主体”部分,其中“头”部提供关于网页的信息,“主体”部分提供网页的具体内容。
HTTP是一个客户端和服务器端请求和应答的标准。客户端是终端用户,服务器端是网站。通过使用Web浏览器、网络爬虫或者其他的工具,客户端发起一个到服务器上指定端口(默认端口为80,HTTPS网站默认端口为443)的HTTP请求。
HTTP协议是基于TCP协议之上建立的,有时也会承载于TLS或SSL协议之上,这时候HTTP协议就变成了加密的HTTPS协议。
通常,由HTTP客户端发起一个请求,建立一个到服务器指定端口的TCP连接,HTTP服务器则在那个端口监听客户端发送过来的请求。一旦收到请求,服务器(向客户端)发回一个状态行,比如“HTTP/1.1 200 OK”,以及响应的消息,消息的消息体可能是请求的文件、错误消息或者其他一些信息。
HTTP协议包含请求体和响应体,最简单的HTTP协议的请求体:
GET / HTTP/1.1
Host: www.baidu.com
User-Agent: curl/7.55.1
Accept: */*
这段请求的目标地址是www.baidu.com,User-Agent为curl,表示这个请求是由curl这个工具发出的,请求的地址为目标地址的根目录“/”。服务端接收到后,会做出响应的回应,响应体主要包含响应头和响应内容:
HTTP/1.1 200 OK
Accept-Ranges: bytes
Cache-Control: private, no-cache, no-store, proxy-revalidate, notransform
Connection: Keep-Alive
Content-Length: 2381
Content-Type: text/html
Date: Sun, 25 Aug 2019 12:13:07 GMT
Etag: "588604dc-94d"
Last-Modified: Mon, 23 Jan 2017 13:27:56 GMT
Pragma: no-cache
Server: bfe/1.0.8.18
Set-Cookie: BDORZ=27315; max-age=86400; domain=.baidu.com; path=/
<!DOCTYPE html>
<!--STATUS OK--><html>
……
17.1.2 URL地址
URL(Uniform Resource Locator)是统一资源定位符,是对可以从互联网上得到的资源的位置和访问方法的一种简洁的表示,是互联网上标准资源的地址。互联网上的每个文件都有一个唯一的URL,它包含的信息指出文件的位置以及浏览器应该怎么处理它。
基本URL包含模式(或称协议)、服务器名称(或IP地址)、路径和文件名。
协议://主机地址/路径?查询
https://www.baidu.com/s?wd=Go语言
完整的、带有授权部分的普通统一资源标志符语法:
协议://用户名:密码@子域名.域名.顶级域名:端口号/目录/文件名.文件后缀?参数=值#标志
http://admin:password@ceshi.baidu.com:8080/dir/test.php?id=1#flag=1
URL的长度有限制,不同的服务器限制值不同:
- IE(Browser):对URL的最大限制为2083个字符。
- Firefox(Browser):URL的长度限制为65536个字符。
- Safari(Browser):URL最大长度限制为80000个字符。
- Opera(Browser):URL最大长度限制为190000个字符。
- Chrome(Browser):URL最大长度限制为8182个字符。
- Apache(Server):能接受最大URL长度为8192个字符。
- Microsoft Internet Information Server(IIS):能接受最大URL长度为16384个字符。
17.1.3 Web工作方式
浏览器本身是一个客户端(手机端客户端内部也是浏览器实现的),当输入URL的时候,首先浏览器会去请求DNS服务器,通过DNS获取相应的域名对应的IP:
www.example.com => DNS服务器 => 获取域名地址为1.1.1.1
然后,浏览器通过IP地址找到对应的服务器,要求建立TCP连接,等浏览器发送完HTTP请求包,服务器接收到请求后开始处理请求包,服务器调用自身服务,返回HTTP响应包,客户端收到来自服务器的响应后开始渲染这个响应包里的主体body,等收到全部的内容后断开与该服务器之间的TCP连接。
17.2 HTTP客户端
HTTP请求的整个过程:用户通过浏览器或其他客户端向服务器发起请求传递request对象,服务器接收request对象,并给出响应,回复response对象。在HTTP客户端发起请求时,经常需要请求不同的资源,这时就需要使用服务端的路由机制,通过不同的请求地址进行相应的路由,如通过GET /user/{id}就能定位到该使用哪个接口来处理这次的请求,user就是路由,而id为路由使用到的方法所需要的参数。
GET /user/1541
PUT /user/1212
在Web开发过程中,我们最常见到的路由风格为RESTfu。
HTTP路由也称路径映射机制,负责将HTTP请求交给对应的方法函数进行处理,可以理解为通过使用不同的请求地址来获取不同的资源。
17.2.1 REST
REST(Representational State Transfer)是一个标准、一种规范,遵循REST风格可以使开发的接口通用,便于调用者理解接口的作用,使用这种风格可以清晰地了解一个请求的目的是什么。
RESTful架构风格规定,数据的元操作,即CRUD(create,read,update和delete,即数据的增查改删)操作,分别对应四种HTTP操作:POST用来新建资源(也可以用于更新资源),GET用来获取资源,PUT用来更新资源,DELETE用来删除资源。这样就统一了数据操作的接口,仅通过HTTP方法,就可以完成对数据的所有增查改删工作。即
- GET(READ):从服务器取出资源(一项或多项)。
- POST(CREATE):在服务器新建一个资源。
- PUT(UPDATE):在服务器更新资源(客户端提供完整资源数据)。
- PATCH(UPDATE):在服务器更新资源(客户端提供需要修改的资源数据)。
- DELETE(DELETE):从服务器删除资源。
REST风格架构有如下约束:
- 使用客户/服务器模型。客户和服务器之间通过一个统一的接口来互相通信。
- 层次化的系统。在一个REST系统中,客户端并不会固定地与一个服务器打交道。
- 无状态。在一个REST系统中,服务端并不会保存有关客户的任何状态。也就是说,客户端自身负责用户状态的维持,并在每次发送请求时都需要提供足够的信息。
- 可缓存。REST系统需要能够恰当地缓存请求,以尽量减少服务端和客户端之间的信息传输,提高性能。
- 统一的接口。一个REST系统需要使用一个统一的接口来完成子系统之间以及服务与用户之间的交互,这使得REST系统中的各个子系统可以独自完成演化。
REST是面向资源的,这个概念非常重要,而资源是通过URI进行暴露的。URI的设计只要负责把资源通过合理方式暴露出来就可以了,对资源的操作与它无关,操作是通过HTTP动词来体现的,所以REST通过URI暴露资源时,会强调不要在URI中出现动词。
GET /rest/api/user 获取一个用户信息
POST /rest/api/user 添加一个用户信息
PUT /rest/api/user/: user_id 更新一个用户信息
DELETE /rest/api/user/:user_id 删除一个用户信息
路由不是固定的,而是多变的,所以我们在服务器端做路由适配,通过不同的路由去匹配不同的处理器,处理不同的请求,这就又引出了两个新的对象,即路由转接器ServeMux和处理器Handler。
17.2.2 Client和Request
Client的结构体类型
type Client struct {
Transport RoundTripper
CheckRedirect func(req *Request, via []*Request) error
Jar CookieJar
Timeout time.Duration
}
- Transport指定执行独立、单次HTTP请求的机制。如果Transport为nil,则使用DefaultTransport。
- CheckRedirect指定处理重定向的策略。如果CheckRedirect不为nil,客户端会在执行重定向之前调用本函数字段。参数req和via是将要执行的请求和已经执行的请求(切片,越新的请求越靠后)。如果CheckRedirect返回一个错误,本类型的GET方法不会发送请求req,而是返回之前得到的最后一个回复和该错误(包装进url.Error类型里)。如果CheckRedirect为nil,会采用默认策略:连续十次请求后停止。
- Jar指定Cookie管理器。如果Jar为nil,请求中不会发送Cookie,回复中的Cookie会被忽略。
- Timeout指定本类型的值执行请求的时间限制。该超时限制包括连接时间、重定向和读取回复主体的时间。计时器会在Head、Get、Post或Do方法返回后继续运作,并在超时后中断回复主体的读取。Timeout为零值表示不设置超时。
Client类型主要充当浏览器的角色,它拥有如下方法:
func (c *Client) Do(req *Request) (resp *Response, err error)
func (c *Client) Head(url string) (resp *Response, err error)
func (c *Client) Get(url string) (resp *Response, err error)
func (c *Client) Post(url string, bodyType string, body io.Reader)
(resp *Response, err error)
func (c *Client) PostForm(url string, data url.Values) (resp
*Response, err error)
Request主要是对请求体的封装,任何形式的HTTP请求都可以使用Request来构造,构造完后使用Client端发送请求。Request的结构体如下:
type Request struct {
Method string // 请求方法
URL *url.URL // 请求地址
Proto string // 协议版本,"HTTP/1.0"
ProtoMajor int // 协议主版本号,“1”
ProtoMinor int // 协议主副版本号,“0”
Header Header // 请求头
Body io.ReadCloser // 请求的Body
ContentLength int64 // ContentLength记录相关内容的长度
TransferEncoding []string // TransferEncoding按从最外到最里的顺序列出传输编码
Close bool // Close在服务端指定是否在回复请求后关闭连接,在客户端指定是否在发送请求后关闭连接
Host string // Host指定URL会在其上寻找资源的主机
Form url.Values // Form是解析好的表单数据,包括URL字段的query参数和POST或PUT的表单数据
PostForm url.Values // PostForm是解析好的POST或PUT的表单数据
MultipartForm *multipart.Form // MultipartForm是解析好的多部件表单,包括上传的文件
Trailer Header // Trailer指定了会在请求主体之后发送的额外的头域
RemoteAddr string // RemoteAddr允许HTTP服务器和其他软件记录该请求的来源地址,一般用于日志
RequestURI string // RequestURI是被客户端发送到服务端的请求中未修改的URI
TLS *tls.ConnectionState // TLS字段允许HTTP服务器和其他软件记录接收到该请求的TLS连接的信息
}
对于Request,需要掌握的成员字段有Method设置请求方法,如果是需要使用GET方法就设置为“GET”。URL字段为请求的地址。
对于模拟客户端发起请求,我们经常需要设置请求头Header,HTTP规定头的键名(头名)是大小写敏感的,请求的解析器通过规范化请求头的键名来实现这一点。
Accept-Encoding: gzip, deflate
Accept-Language: en-us
Connection: keep-alive
还有一个重要的成员为Form,Form是解析好的表单数据,包括URL字段的query参数和POST或PUT的表单数据,该字段只有在调用ParseForm后才有效。如果需要模拟上传文件,则需要使用MultipartForm成员。
在客户端进行请求数据时,使用最多的请求方法为GET和POST
- GET——从指定的资源请求数据
- POST——向指定的资源提交要被处理的数据
GET和POST是表单提交数据的两种基本方式。GET请求数据通过域名后缀url传送,用户可见,不安全;POST请求数据在请求报文正文里传输,相对比较安全。
GET用于请求指定的页面信息,并返回实体主体。特点:
- GET请求可被缓存。
- GET请求保留在浏览器历史记录中。
- GET请求可被收藏为书签。
- GET请求不应在处理敏感数据时使用。
- GET请求有长度限制。
- GET请求只应当用于取回数据。
POST用于向指定资源提交数据进行处理请求(例如提交表单或者上传文件)。数据被包含在请求体中。POST请求可能会导致新的资源的建立和(或)已有资源的修改。特点:
- POST请求不会被缓存。
- POST请求不会保留在浏览器历史记录中。
- POST不能被收藏为书签。
- POST请求对数据长度没有要求。
对于GET方式的请求,浏览器会把HTTP header和data一并发送出去,服务器响应200并返回数据。而对于POST,浏览器先发送header,服务器响应100 continue,浏览器再发送data,服务再响应200并返回数据。并不是所有浏览器都会在POST中发送两次包,如Firefox就只发送一次。
Go语言中Client类型的GET和POST方法,在数据传输过程中分别对应了HTTP协议中的GET和POST方法。二者主要区别如下:
- GET是用来从服务器上获得数据,而POST是用来向服务器传递数据。
- GET将表单中的数据按照variable=value的形式,添加到action所指向的URL后面,并且两者使用“?”连接,而各个变量之间使用“&”连接;POST是将表单中的数据放在form的数据体中,按照变量和值相对应的方式,传递到action所指向的URL。
- GET是不安全的,因为在传输过程中,数据被放在请求的URL中,而如今现有的很多服务器、代理服务器或者用户代理都会将请求URL记录到日志文件中,然后放在某个地方,这样就可能会有一些隐私的信息被第三方看到。另外,用户也可以在浏览器上直接看到提交的数据,一些系统内部消息将会一同显示在用户面前。而POST的所有操作对用户来说都是不可见的。
- GET传输的数据量小,这主要是因为受URL长度限制,而POST可以传输大量的数据,所以在上传文件时只能使用POST。
- GET限制Form表单的数据集的值必须为ASCII字符,而POST支持整个ISO 10646字符集。
- 使用POST传输的数据,可以通过设置编码的方式正确转化中文,而GET传输的数据却没有变化。
- POST会有浏览器提示重新提交表单的问题,GET则没有。
17.2.3 发起GET请求
发起请求前需要创建一个请求对象,使用NewRequest创建。
func NewRequest(method, urlStr string, body io.Reader) (*Request, error)
NewRequest使用指定的方法、网址和可选的body创建并返回一个新的*Request。
package main
import (
"fmt"
"net/http"
)
func main() {
client := &http.Client{}
request, err := http.NewRequest("GET", "http://www.baidu.com", nil)
if err != nil {
fmt.Println(err)
}
response, err := client.Do(request)
fmt.Println(response.StatusCode)
}
如果想要打印响应的主要内容body,可以使用标准包ioutil中的ReadAll方法来读取响应的流数据。
response, err := client.Do(request)
res, err := ioutil.ReadAll(response.Body)
if err != nil {
fmt.Println(err)
}
fmt.Println(string(res))
当一个网站有一些资源需要登录后才能访问时,我们希望能够通过Go语言实现批量自动化爬取这些内容,那如何让服务器知道我们用Go编写的爬虫客户端是已登录状态?这就需要设置使用Cookie,Cookie通常用来标识客户端的登录状态。Request实例可以使用AddCookie方法给请求添加Cookie。
package main
import (
"fmt"
"net/http"
"strconv"
)
func main() {
client := &http.Client{}
request, err := http.NewRequest("GET", "http://www.baidu.com", nil)
if err != nil {
fmt.Println(err)
}
//使用http.Cookie结构体初始化一个cookie键值对
cookie := &http.Cookie{Name: "userId", Value: strconv.Itoa(12345)}
request.AddCookie(cookie)
request.AddCookie(&http.Cookie{Name: "session", Value: "YWRtaW4="})
response, err := client.Do(request)
fmt.Println(response.Request.Cookies())
}
做了反爬策略的网站,一般都会根据Header头中的User-Agent的值解析判断是浏览器还是爬虫,这时我们需要设置成浏览器的UA来绕过这类反爬策略。Request可以直接使用request.Header.Set(key,value)来设置Header。
package main
import (
"fmt"
"net/http"
)
func main() {
client := &http.Client{}
request, err := http.NewRequest("GET", "http://www.baidu.com", nil)
if err != nil {
fmt.Println(err)
}
//设置header
request.Header.Set("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8")
request.Header.Set("Accept-Charset", "GBK,utf-8;q=0.7,*;q=0.3")
request.Header.Set("Accept-Encoding", "gzip, deflate, sdch")
request.Header.Set("Cache-Control", "max-age=0")
request.Header.Set("Connection", "keep-alive")
request.Header.Set("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:102.0) Gecko/20100101 Firefox/102.0")
response, err := client.Do(request)
fmt.Printf("%#v", response.Request.Header)
}
http包中也有一个叫GET的方法,底层就是调用Client的GET方法。
package main
import (
"fmt"
"io/ioutil"
"net/http"
)
func main() {
response, err := http.Get("http://www.baidu.com")
if err != nil {
fmt.Println(err)
}
defer response.Body.Close()
body, _ := ioutil.ReadAll(response.Body)
fmt.Println(string(body))
}
17.2.4 发起post请求
http.NewRequest来创建一个请求,http.NewRequest有三个参数,第一个是请求方法Method,第二个是请求地址URL,最后一个参数是body,其类型为io.Reader。GET方法不需要使用body参数,只需传入nil即可,如果是POST请求,则需要使用该参数。
如果body参数实现了io.Closer接口,Request返回值的Body字段会被设置为body,并会被Client类型的Do、Post和PostForm方法以及Transport.RoundTrip方法关闭。
package main
import (
"fmt"
"io/ioutil"
"net/http"
"strings"
)
func main() {
client := &http.Client{}
//使用NopCloser创建一个实现io.Closer接口的body
body := ioutil.NopCloser(strings.NewReader("user=admin&pass=admin"))
req, err := http.NewRequest("POST", "http://www.baidu.com", body)
if err != nil {
fmt.Println(err)
}
req_body, err := ioutil.ReadAll(req.Body)
fmt.Println(string(req_body))
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
resp, err := client.Do(req)
if err != nil {
fmt.Println(err)
}
req_body, err = ioutil.ReadAll(resp.Request.Body)
if err != nil {
fmt.Println(err)
}
fmt.Println(string(req_body))
}
使用http包的post方法
package main
import (
"fmt"
"io/ioutil"
"net/http"
"strings"
)
func main() {
resp, err := http.Post("http://www.baidu.com", "application/x-www-form-urlencoded", strings.NewReader("user=admin&pass=admin"))
if err != nil {
fmt.Println(err)
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
fmt.Println(err)
}
fmt.Println(string(body))
}
除了POST方法,http包还封装了一个叫PostForm的方法。
func PostForm(url string, data url.Values) (resp *Response, err error)
PostForm向指定的URL发出一个POST请求,url.Values类型的data会被编码为请求的主体。如果返回值err为nil,resp.Body总是非nil的,调用者应该在读取完resp.Body后关闭它。该方法是对Client的PostForm方法的包装。
package main
import (
"fmt"
"io/ioutil"
"net/http"
"net/url"
)
func main() {
resp, err := http.PostForm("http://www.baidu.com", url.Values{"user": {"admin"}, "pass": {"admin"}})
if err != nil {
fmt.Println(err)
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
fmt.Println(err)
}
fmt.Println(string(body))
}
17.3 爬虫框架gocolly
colly是用Go语言实现的网络爬虫框架。colly快速优雅,在单核上每秒可以发起1K以上请求;以回调函数的形式提供了一组接口,可以实现任意类型的爬虫。
17.3.1 gocolly简介
colly的代码托管在GitHub上,官方网站为http://go-colly.org/。colly使用起来简洁高效,特性:
- 非常清晰的API。
- 快速(单核上>1K请求/秒)。
- 管理请求延迟和每个域的最大并发数。
- 自动Cookie和会话处理。
- 同步/异步/并行抓取。
- 高速缓存。
- 自动处理非Unicode的编码。
- Robots.txt支持。
- 分布式抓取。
- 通过环境变量配置。
- 可扩展。
下载命令:
go get -u github.com/gocolly/colly
colly的主要实体是一个Collector对象。Collector在收集器作业运行时管理网络通信并负责执行附加的回调。要使用colly,必须先初始化Collector:
c := colly.NewCollector()
一旦得到一个colly对象,就可以向colly附加各种不同类型的回调函数(回调函数在colly中广泛使用)来控制收集作业或获取信息:
// 请求发送前所运行的函数
c.OnRequest(func(r *colly.Request) {
fmt.Println("Visiting", r.URL)
})
// 遇到错误时所运行的函数
c.OnError(func(_ *colly.Response, err error) {
log.Println("Something went wrong:", err)
})
// 接收到响应后所运行的函数
c.OnResponse(func(r *colly.Response) {
fmt.Println("Visited", r.Request.URL)
})
// 接收到HTML网页后所运行的函数
c.OnHTML("a[href]", func(e *colly.HTMLElement) {
e.Request.Visit(e.Attr("href"))
})
c.OnHTML("tr td:nth-of-type(1)", func(e *colly.HTMLElement) {
fmt.Println("First column of a table row:", e.Text)
})
// 接收到XML格式的响应内容后所运行的函数
c.OnXML("//h1", func(e *colly.XMLElement) {
fmt.Println(e.Text)
})
// 请求完成后所运行的函数
c.OnScraped(func(r *colly.Response) {
fmt.Println("Finished", r.Request.URL)
})
colly的回调函数非常清晰,比如OnRequest表示在请求之前所需要做的事情,OnResponse表示在获取到响应后所做的事情。
package main
import (
"fmt"
"github.com/gocolly/colly"
)
func main() {
c := colly.NewCollector()
//查找和访问所有的链接
c.OnHTML("a[href]", func(e *colly.HTMLElement) {
e.Request.Visit(e.Attr("href"))
})
c.OnRequest(func(r *colly.Request) {
fmt.Println("Visiting ", r.URL)
})
c.Visit("http://go-colly.org/")
}
访问全站链接:
这里我手动停止了
NewCollector在初始化时,可以传入colly.UserAgent来设置请求的UA,绕过网站的反爬策略。OnRequest一般会在请求前设置一些模拟真实浏览器的Header头:
package main
import (
"fmt"
"github.com/gocolly/colly"
)
func main() {
c := colly.NewCollector(
colly.UserAgent("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Safari/537.36"))
c.OnRequest(func(r *colly.Request) {
r.Headers.Set("Connection", "keep-alive")
r.Headers.Set("Accept", "*/*")
r.Headers.Set("Origin", "")
r.Headers.Set("Accept-Encoding", "gzip,deflate")
r.Headers.Set("Accept-Language", "zh-CN,zh;q=0.9")
fmt.Println("Visiting", r.URL)
})
//打印响应状态码
c.OnResponse(func(r *colly.Response) {
fmt.Println("Response recevied ", r.StatusCode)
})
//对响应的HTML元素处理
c.OnHTML("title", func(e *colly.HTMLElement) {
fmt.Println("title :", e.Text)
})
c.Visit("https://www.baidu.com")
}
17.3.2 实战爬取西刺代理IP
略,目标网址已经挂掉了
17.5 知识拓展
curl工具详解
17.5.1curl简介
curl是一个利用URL语法在命令行下工作的文件传输工具,于1997年首次发行。它支持文件上传和下载,所以是综合传输工具,但按传统,习惯称curl为下载工具。curl还包含了用于程序开发的libcurl。
curl支持的通信协议有FTP、FTPS、HTTP、HTTPS、TFTP、SFTP、Gopher、SCP、TELNET、DICT、FILE、LDAP、LDAPS、IMAP、POP3、SMTP和RTSP。
该工具的官网地址为:https://curl.haxx.se。
17.5.2 curl安装
对于Linux系统而言,系统已默认安装此工具,无须再次安装。对于Windows系统,大部分发行版本都默认没有安装curl工具,部分系统如Win10已默认安装。对于没有安装curl工具的系统,可自行下载安装包安装,下载地址为:https://curl.haxx.se/windows/。
17.5.3 curl常见命令
-
查看网页源码
curl https://curl.haxx.se
如果要把这个网页保存下来,可以使用-o参数:
curl -o https://curl.haxx.se
-
显示头信息
-i参数可以显示HTTP的Response的头信息,连同网页代码一起。-I参数则只显示HTTP的Response的头信息。
curl -i https://curl.haxx.se
-
显示通信过程
-v参数可以显示一次http通信的整个过程,包括端口连接和HTTP的Request头信息。
curl -v https://curl.haxx.se
-
发送表单信息
发送表单信息有GET和POST两种方法。GET方法相对简单,只要把数据附在网址后面即可。
curl example.com/form.cgi?data=xxx
POST方法必须把数据和网址分开,curl就要用到–data或者-d参数。
curl -X POST --data "data=xxx" example.com/form.cgi
-
选择使用的请求方法
默认的HTTP请求方法是GET,使用-X参数可以支持其他方法。
01 curl -X POST https://curl.haxx.se 02 curl -X PUT https://curl.haxx.se
-
设置UA
–user-agent参数用来表示客户端的设备信息,服务器有时会根据这个字段,针对不同设备返回不同格式的网页,比如手机版和桌面版。
curl --user-agent "[User Agent]" https://curl.haxx.se
-
设置Cookie
使用–cookie参数,可以让curl发送Cookie。
curl --cookie "name=xxx" https://curl.haxx.se
-
增加头信息
有时需要在HTTP的Request之中自行增加一个头信息,–header参数就可以起到这个作用。
curl --header "Content-Type:application/json" http://example.com