发送一个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部分代码如下
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部分代码来理解。
请求行包含三个部分,分别为 请求类型``请求URL``协议版本
> POST / HTTP/1.1 # [请求类型] [请求URL] [协议版本]
本次请求的请求类型为 POST
,常见的请求类型如下
GET
# 请求获取Request-URL所标识的资源POST
# 在Request-URL所标识的资源后附加新的数据HEAD
# 请求获取由Request-URL所标识的资源的响应消息报头PUT
# 请求服务器存储一个资源并用Request-URL作为标识DELETE
# 请求服务器删除Request-URL所标识的资源TRACE
# 请求服务器回送收到的请求消息,主要用于测试或诊断CONNECT
# 保留将来使用OPTIONS
# 请求查询服务器性能、查询资源相关选项、预检请求本次请求的请求URL为 /
本次请求的协议版本为HTTP 1.1,常见的协议版本如下
消息报头有很多种字段类型,本次请求包含如下五个消息报头
> Host: www.hagan.zone # 消息报头
> User-Agent: curl/7.64.1 # 消息报头
> Accept: */* # 消息报头
> Content-Length: 10 # 消息报头
> Content-Type: application/x-www-form-urlencoded # 消息报头
常见的消息报头如下
指定客户端接受哪些类型的信息
text/html
# HTML文本image/gif
# gif图片*/*
# 啥都行客户端接受的字符集
gb2312
# 中文字符iso-8859-1
# 西文字符集utf-8
# 多语言字符可接受的内容编码
gzip
# 压缩类型deflate
# 压缩类型identity
# 默认指定一种自然语言
zh-cn
# 中文证明客户端有权查看某个资源
指定被请求资源的Internet主机和端口号
用户代理
Body编码方式
请求正文有很多种编码方式,请求正文的类型需要根据消息报头的Content-Type
字段来确定,本次请求的编码方式为application/x-www-form-urlencoded
> Content-Type: application/x-www-form-urlencoded # 消息报头
常见的Content-Type类型如下
默认数据编码方式
?name=hagan&age=22
序列化后的JSON字符串
XML作为编码方式的远程调用规范
数据以纯文本形式进行编码
允许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)--
只能通过流的方式提交一个二进制或文件
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部分代码来理解。
状态行包含三个部分,分别为 协议版本``状态码``状态信息
< HTTP/1.1 301 Moved Permanently # 状态行 # [协议版本] [状态码] [状态信息]
本次响应的协议版本为 HTTP/1.1
,常见协议版本如下
本次响应的状态码为 301
,常见状态码如下
指示信息,表示请求已接收,继续处理
成功,表示请求已被成功接收、理解、接受
200
OK,请求成功201
Created,对于那些要服务器创建对象的请求来说,资源已创建完毕202
Accepted,请求已接受,但服务器尚未处理204
No Content,Response包含状态行和消息报头,但不包含响应正文206
Partial Content,部分请求成功重定向,要完成请求必须进行更进一步的操作
301
请求永久重定向至新URL302
请求临时重定向至新URL客户端错误。请求有语法错误或请求无法实现
400
Bad Request,错误的请求401
Unauthorized,需要客户端认证403
Forbidden,请求被服务器拒绝404
Not Found,未找到资源服务端错误,服务端未能实现合法的请求
500
Internal Server Error,内部服务器错误503
Server Unavailable,服务器暂时无法提供服务,一段时间后便可恢复服务本次响应的状态信息为 Moved Permanently
,常见状态信息如下
Response中的消息报头主要分为 响应报头
和 实体报头
本次响应中的响应报头包含如下三个
< Server: nginx/1.18.0 # 响应报头
< Date: Fri, 30 Jul 2021 01:26:20 GMT # 响应报头
< Location: https://www.hagan.zone/ # 响应报头
常见的响应报头如下
重定向接受者到一个新的位置
包含在401响应消息中,客户端收到401
包含了服务器用来处理请求的软件信息
Apache- Coyote/1.1
实体报头也叫正文报头,本次响应中的实体报头包含如下三个
< Content-Type: text/html # 实体报头
< Content-Length: 169 # 实体报头
< Connection: keep-alive # 实体报头
常见的实体报头如下
编码类型是压缩还是非压缩
eg: Content-Encoding: gzip
资源所用的自然语言,没有设置该域则认为实体内容将提供给所有的语言阅读
正文的长度,以字节方式存储的十进制数字表示
响应正文的媒体类型
响应过期的日期和时间
响应正文有很多种类型,响应正文的类型需要根据消息报头的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
,也可点击阅读原文直接跳转到文章详情页,里面会包含我最新的修改。
Copyright© 2013-2020
All Rights Reserved 京ICP备2023019179号-8