从curl命令行视角来讲解HTTP请求
共 7634字,需浏览 16分钟
·
2021-09-05 16:38
发送一个HTTP请求有很多途径,例如浏览器、curl命令行、wget命令行等。本文将带你从curl命令行视角来讲解一个http请求中各个不同数据字段的含义
我们先来简单讲解一下 curl
命令。
curl 是一个用来请求 Web 服务器的命令行工具,-v
代表输出通信的整个过程,-d
代表发送 一个POST 请求并在请求正文中带上指定数据,使用方式如下
curl -v -d 'name=hagan' http://www.hagan.zone # 使用post方式请求url并带上数据
请求完整过程如下
hagan@hanyonggang life % curl -v -d 'name=hagan' http://www.hagan.zone
* Trying 42.193.104.246...
* TCP_NODELAY set
* Connected to www.hagan.zone (42.193.104.246) port 80 (#0)
> POST / HTTP/1.1
> Host: www.hagan.zone
> User-Agent: curl/7.64.1
> Accept: */*
> Content-Length: 10
> Content-Type: application/x-www-form-urlencoded
>
* upload completely sent off: 10 out of 10 bytes
< HTTP/1.1 301 Moved Permanently
< Server: nginx/1.18.0
< Date: Fri, 30 Jul 2021 01:26:20 GMT
< Content-Type: text/html
< Content-Length: 169
< Connection: keep-alive
< Location: https://www.hagan.zone/
<
<html>
<head><title>301 Moved Permanently</title></head>
<body>
<center><h1>301 Moved Permanently</h1></center>
<hr><center>nginx/1.18.0</center>
</body>
</html>
* Connection #0 to host www.hagan.zone left intact
* Closing connection 0
本文将详细剖析以上数据
Request
Request代表发送请求部分,示例中Request部分代码如下
hagan@hanyonggang life % curl -v -d 'name=hagan' http://www.hagan.zone
* Trying 42.193.104.246...
* TCP_NODELAY set
* Connected to www.hagan.zone (42.193.104.246) port 80 (#0)
> POST / HTTP/1.1 # [请求类型] [请求URL] [协议版本]
> Host: www.hagan.zone # 消息报头
> User-Agent: curl/7.64.1 # 消息报头
> Accept: */* # 消息报头
> Content-Length: 10 # 消息报头
> Content-Type: application/x-www-form-urlencoded # 消息报头
>
* upload completely sent off: 10 out of 10 bytes
Request包含三个部分,分别为 请求行
消息报头(Header)
请求正文(Body)
下面的讲解请参考示例中Request部分代码来理解。
1.请求行
请求行包含三个部分,分别为 请求类型
请求URL
协议版本
> POST / HTTP/1.1 # [请求类型] [请求URL] [协议版本]
1.请求类型
本次请求的请求类型为 POST
,常见的请求类型如下
GET
# 请求获取Request-URL所标识的资源POST
# 在Request-URL所标识的资源后附加新的数据HEAD
# 请求获取由Request-URL所标识的资源的响应消息报头PUT
# 请求服务器存储一个资源并用Request-URL作为标识DELETE
# 请求服务器删除Request-URL所标识的资源TRACE
# 请求服务器回送收到的请求消息,主要用于测试或诊断CONNECT
# 保留将来使用OPTIONS
# 请求查询服务器性能、查询资源相关选项、预检请求
2.请求URL
本次请求的请求URL为 /
3.协议版本
本次请求的协议版本为HTTP 1.1,常见的协议版本如下
HTTP/1.0 HTTP/1.1 HTTP/2.0
2.消息报头(Header)
消息报头有很多种字段类型,本次请求包含如下五个消息报头
> Host: www.hagan.zone # 消息报头
> User-Agent: curl/7.64.1 # 消息报头
> Accept: */* # 消息报头
> Content-Length: 10 # 消息报头
> Content-Type: application/x-www-form-urlencoded # 消息报头
常见的消息报头如下
Accept
指定客户端接受哪些类型的信息
text/html
# HTML文本image/gif
# gif图片*/*
# 啥都行
Accept-Charset
客户端接受的字符集
gb2312
# 中文字符iso-8859-1
# 西文字符集utf-8
# 多语言字符
Accept-Encoding
可接受的内容编码
gzip
# 压缩类型deflate
# 压缩类型identity
# 默认
Accept-Language
指定一种自然语言
zh-cn
# 中文
Authorization
证明客户端有权查看某个资源
Host
指定被请求资源的Internet主机和端口号
hagan.zone:8080
User-Agent
用户代理
操作系统及版本 CPU类型 浏览器及版本 浏览器渲染引擎 浏览器语言 浏览器插件
Content-Type
Body编码方式
3.请求正文(Body)
请求正文有很多种编码方式,请求正文的类型需要根据消息报头的Content-Type
字段来确定,本次请求的编码方式为application/x-www-form-urlencoded
> Content-Type: application/x-www-form-urlencoded # 消息报头
常见的Content-Type类型如下
application/x-www-form-urlencoded
默认数据编码方式
?name=hagan&age=22
application/json
序列化后的JSON字符串
text/xml
XML作为编码方式的远程调用规范
text/plain
数据以纯文本形式进行编码
multipart/form-data
允许body里面包含多个模块,每个模块可以是不同类型,常用于文件上传
需要规定一个用于分割模块的分隔符 boundary
Content-Type: multipart/form-data; boundary=hagan # boundary为分隔符
当指定分隔符为 hagan
时请求体格式如下
--hagan
Content-Disposition: form-data; name="fullname" # name为参数名
haganhan # 参数值 # 规范规定参数值前面必须有两个换行符
--hagan
Content-Disposition: form-data; name="head"; filename="head.png"
Content-Type: image/png # 指定类型
<Buffer 00> # 参数值
--hagan-- # 请求体结束
整个请求体拼装完成后 , 最后会以--分隔符--结尾 --hagan--
--分隔符(boundary)
Content-Disposition: form-data; name="参数名1"
参数值1
--分隔符(boundary)
Content-Disposition: form-data; name="参数名2"
参数值2
--分隔符(boundary)
Content-Disposition: form-data; name="参数名3"
参数值3
--分隔符(boundary)
Content-Disposition: form-data; name="图片名1"; filename="图片文件名1"
Content-Type: 类型
图片文件的二进制内容1
--分隔符(boundary)
Content-Disposition: form-data; name="图片名2"; filename="图片文件名2"
Content-Type: 类型
图片文件的二进制内容2
--分隔符(boundary)
Content-Disposition: form-data; name="图片名3"; filename="图片文件名3"
Content-Type: 类型
图片文件的二进制内容3
--分隔符(boundary)--
application/octet-stream
只能通过流的方式提交一个二进制或文件
Response
Response代表服务端响应部分,示例中Response部分代码如下
< HTTP/1.1 301 Moved Permanently # 状态行 # [协议版本] [状态码] [状态信息]
< Server: nginx/1.18.0 # 响应报头
< Date: Fri, 30 Jul 2021 01:26:20 GMT # 响应报头
< Content-Type: text/html # 实体报头
< Content-Length: 169 # 实体报头
< Connection: keep-alive # 实体报头
< Location: https://www.hagan.zone/ # 响应报头
<
<html>
<head><title>301 Moved Permanently</title></head>
<body>
<center><h1>301 Moved Permanently</h1></center>
<hr><center>nginx/1.18.0</center>
</body>
</html>
* Connection #0 to host www.hagan.zone left intact
* Closing connection 0
Response也包含三个部分,分别为 状态行
消息报头(Header)
响应正文(Body)
,下面将详细讲解这三部分。
下面的讲解请参考示例中Response部分代码来理解。
1.状态行
状态行包含三个部分,分别为 协议版本
状态码
状态信息
< HTTP/1.1 301 Moved Permanently # 状态行 # [协议版本] [状态码] [状态信息]
1.协议版本
本次响应的协议版本为 HTTP/1.1
,常见协议版本如下
HTTP/1.0 HTTP/1.1 HTTP/2.0
2.状态码
本次响应的状态码为 301
,常见状态码如下
1xx
指示信息,表示请求已接收,继续处理
2xx
成功,表示请求已被成功接收、理解、接受
200
OK,请求成功201
Created,对于那些要服务器创建对象的请求来说,资源已创建完毕202
Accepted,请求已接受,但服务器尚未处理204
No Content,Response包含状态行和消息报头,但不包含响应正文206
Partial Content,部分请求成功
3xx
重定向,要完成请求必须进行更进一步的操作
301
请求永久重定向至新URL302
请求临时重定向至新URL
4xx
客户端错误。请求有语法错误或请求无法实现
400
Bad Request,错误的请求401
Unauthorized,需要客户端认证403
Forbidden,请求被服务器拒绝404
Not Found,未找到资源
5xx
服务端错误,服务端未能实现合法的请求
500
Internal Server Error,内部服务器错误503
Server Unavailable,服务器暂时无法提供服务,一段时间后便可恢复服务
3.状态信息
本次响应的状态信息为 Moved Permanently
,常见状态信息如下
OK Moved Permanently Not Found
2.消息报头(Header)
Response中的消息报头主要分为 响应报头
和 实体报头
响应报头
本次响应中的响应报头包含如下三个
< Server: nginx/1.18.0 # 响应报头
< Date: Fri, 30 Jul 2021 01:26:20 GMT # 响应报头
< Location: https://www.hagan.zone/ # 响应报头
常见的响应报头如下
Location
重定向接受者到一个新的位置
WWW- Authenticate
包含在401响应消息中,客户端收到401
Server
包含了服务器用来处理请求的软件信息
Apache- Coyote/1.1
实体报头
实体报头也叫正文报头,本次响应中的实体报头包含如下三个
< Content-Type: text/html # 实体报头
< Content-Length: 169 # 实体报头
< Connection: keep-alive # 实体报头
常见的实体报头如下
Content-Encoding
编码类型是压缩还是非压缩
eg: Content-Encoding: gzip
Content-Language
资源所用的自然语言,没有设置该域则认为实体内容将提供给所有的语言阅读
Content-Length
正文的长度,以字节方式存储的十进制数字表示
Content-Type
响应正文的媒体类型
实体类型列表
Expires
响应过期的日期和时间
3.响应正文(Body)
响应正文有很多种类型,响应正文的类型需要根据消息报头的Content-Type
字段来确定,本次响应的编码方式为text/html
< Content-Type: text/html # 实体报头
响应正文如下
<html>
<head><title>301 Moved Permanently</title></head>
<body>
<center><h1>301 Moved Permanently</h1></center>
<hr><center>nginx/1.18.0</center>
</body>
</html>
* Connection #0 to host www.hagan.zone left intact
* Closing connection 0
curl命令只展示数据,不提供数据的解析,如果是浏览器,则会将响应正文以 text/html
的方式进行解析,此时便得到了一个HTML页面
本文会在我的博客持续更新,欢迎访问我的博客 hagan.zone
,也可点击阅读原文直接跳转到文章详情页,里面会包含我最新的修改。
参考资料
http://www.ruanyifeng.com/blog/2019/09/curl-reference.html