HTTP协议详解

HTTP (HyperText Transfer Protocol)即超文本传输协议是互联网上应用最为广泛的一种网络协议,也是比较基础协议。作为开发者,我们有必要掌握HTTP协议以及背后的技术细节。

变迁

  • HTTP/0.9
    HTTP于1990年问世,那时候并没有建立正式的HTTP标准,之所以被称为HTTP/0.9,是因为它含有HTTP/1.0之前版本的意思。该版本也极其简单,只有一个命令GET,同时协议规定,服务器只能响应HTML格式的字符串,不能响应别的格式。服务器发送完毕后,就会关闭TCP连接。

  • HTTP/1.0
    1996年5月,HTTP/1.0 版本发布。该版本增加了大量的新特性。在原来GET命令的基础上,引入了POST命令、HEAD命令。同时对传输内容放开了限制使得任何格式的内容都可以发送,大大丰富了互联网的内容。同时规范了HTTP请求和回应的格式,规定请求和响应的内容需要包括头和体。

  • HTTP/1.1
    1997年1月,HTTP/1.1 版本发布。进一步完善了 HTTP 协议,该版本也是HTTP主流的协议版本。该版本引入了持久连接,TCP连接默认不关闭,可以被多个请求复用,而不用声明Connection请求头。

  • HTTP/2
    2015年,HTTP/2 发布。该版本的HTTP引用了大量的新特性,同时对原来的HTTP做了许多变革。HTTP/2 彻底二进制化,头信息和数据体都是二进制,这些二进制统称为帧,包含头信息帧和数据帧。HTTP/2 可以在一个连接里同时发送多个请求或响应,而且不用按照顺序一一对应,不用担心请求拥塞。HTTP/2 引入了头信息压缩机制,来降低每次请求与响应的带宽。HTTP/2 引入了服务器推送,允许服务器未经请求,主动向客户端发送数据。

HTTP 报文

用于HTTP交互的信息成为HTTP报文,请求端的报文成为请求报文,响应端的报文叫做响应报文。HTTP报文是由多行数据构成的字符串文本,并由CR+LF作为换行符。这里分析的HTTP协议依然是HTTP/1.1版本,该版本是目前使用得最广泛的协议。

1、请求报文

请求报文主要分为请求行、请求首部(header)、body(请求体)。header 和 body 空行( CR为回车符,LF换行符 )。以下CRLF均表示回车加换行。

HTTP协议详解_第1张图片
HTTP请求报文结构.png

请求报文抓包:

GET / HTTP/1.1
Host: www.jianshu.com
Connection: close
User-Agent: Paw/3.1.5 (Macintosh; OS X/10.12.6) GCDHTTPRequest
  • 请求行

请求行包含了请求的方式(GET、POST、HEAD等),请求的URI以及HTTP协议的版本。

请求方式 空格 请求URI HTTP版本 CRLF

请求行实例:

GET / HTTP/1.1

GET、POST 请求参数附加在URL上的时候,在HTTP发送请求报文的时候会将URL的请求参数放入请求行,如请求 http://www.jianshu.com/?name=iOS&age=10,这里我们加入了name和age两个参数,抓包如下:

HTTP协议详解_第2张图片
屏幕快照 2017-10-16 18.18.13.png

可见这时请求行为:

GET /?name=iOS&age=10 HTTP/1.1
  • 请求首部

请求首部本质就是键值对,是构成HTTP报文的要素之一,它能起到传递额外信息的作用,它的格式如下:

Key: 空格 value CRLF

以下是对的请求报文:

GET /?name=iOS&age=10 HTTP/1.1
name: iOS
Cookie: signin_redirect=http%3A%2F%2Fwww.jianshu.com%2F%3Fname%3DiOS%26age%3D10; _maleskine_session=SGhIVENaem04NWVWSE5UMkVGNWFUTGZSR0hlT2J0dUgyWGJ1bFlMS2h6Smx0UnZ0Mk9tR25zWTBubWJZZmU2UkhUT2RMQ3ZZT0lTQ2U2d3NaVDR3TnBTQ1kwcXgyZHJnNkxsSkI3Q0lFYkxkY0xlbzA1Q1Z2MmRIa1RzNkliQnBFMzJQUmRIeXY3MXI0Wk1zZjd2eGliWkpnSVJiYWNNSk1tMDJpaFN1dURudnZ1YzFUOG1EMkYyL0N6S1JlQzh2YUV6MzNCV1E2ZDhiMStmMndlL05GZElhNFJnTStqSjVsNVg0a3ZQdUY1V1pxQ05ucmdLUkZlUmxhekpzdjg1TS0tWlhEa1gwdmlna1FrR1dsbkZ3WjFqQT09--9e4c4c2ce38d9cea7549bb35f4ba2fa5783c5a45
Host: www.jianshu.com
Connection: close
User-Agent: Paw/3.1.5 (Macintosh; OS X/10.12.6) GCDHTTPRequest

其中除了name是自己添加的键值对外,其它如:name,Cookie,Host 都是HTTP1.1协议支持的首部字段。

  • 请求体

请求体里面包含请求的实际数据。对于GET请求,请求体是为空的。对于POST请求,请求体一般不为空,我们实际的业务数据都存放于请求体当中。

以下是对的请求体,请求体为一段json(application/json)数据:{"name":"ios"}

POST /?name=iOS&age=10 HTTP/1.1
name: iOS
Content-Type: application/json; charset=utf-8
Cookie: signin_redirect=http%3A%2F%2Fwww.jianshu.com%2F%3Fname%3DiOS%26age%3D10; _maleskine_session=SGhIVENaem04NWVWSE5UMkVGNWFUTGZSR0hlT2J0dUgyWGJ1bFlMS2h6Smx0UnZ0Mk9tR25zWTBubWJZZmU2UkhUT2RMQ3ZZT0lTQ2U2d3NaVDR3TnBTQ1kwcXgyZHJnNkxsSkI3Q0lFYkxkY0xlbzA1Q1Z2MmRIa1RzNkliQnBFMzJQUmRIeXY3MXI0Wk1zZjd2eGliWkpnSVJiYWNNSk1tMDJpaFN1dURudnZ1YzFUOG1EMkYyL0N6S1JlQzh2YUV6MzNCV1E2ZDhiMStmMndlL05GZElhNFJnTStqSjVsNVg0a3ZQdUY1V1pxQ05ucmdLUkZlUmxhekpzdjg1TS0tWlhEa1gwdmlna1FrR1dsbkZ3WjFqQT09--9e4c4c2ce38d9cea7549bb35f4ba2fa5783c5a45
Host: www.jianshu.com
Connection: close
User-Agent: Paw/3.1.5 (Macintosh; OS X/10.12.6) GCDHTTPRequest
Content-Length: 14

{"name":"ios"}


2、响应报文

响应报文主要分为状态行、响应首部(header)、body(响应体)。header 和 body 空行( CR为回车符,LF换行符 )

HTTP协议详解_第3张图片
HTTP响应报文结构.png

的响应抓包:

HTTP/1.1 200 OK
Date: Mon, 16 Oct 2017 02:16:07 GMT
Server: Tengine
Content-Type: text/html; charset=utf-8
Transfer-Encoding: chunked
Connection: close






  
......

  • 状态行

状态行主要包含HTTP协议版本、状态码、以及相关原因。

 HTTP版本 空格 状态码 空格 原因 CRLF

以下是请求的状态行

HTTP/1.1 200 OK

常见的状态码:

状态码 类比 说明
1xx Informational (信息性状态码) 接收的请求正在处理
2xx Success( 成功状态码) 请求正常处理完毕
3xx Redirection( 重定向状态码) 需要进行附加操作以完成请求
4xx Client Error (客户端错误状态码) 服务器无法处理请求
5xx Server Error 服务器错误状态码 服务器处理请求出错
  • 响应首部

响应首部本质是键值对,是构成HTTP报文的要素之一,它能起到传递额外信息的作用,它的格式如下:

Key: 空格 value CRLF

以下是对的响应首部报文:

HTTP/1.1 200 OK
Date: Mon, 16 Oct 2017 15:18:46 GMT
Server: Tengine
Content-Type: text/html; charset=utf-8
Transfer-Encoding: chunked
X-Frame-Options: DENY
X-XSS-Protection: 1; mode=block
X-Content-Type-Options: nosniff
Content-Security-Policy: script-src 'self' 'unsafe-inline' 'unsafe-eval' *.jianshu.io api.geetest.com static.geetest.com dn-staticdown.qbox.me zz.bdstatic.com *.google-analytics.com hm.baidu.com push.zhanzhang.baidu.com res.wx.qq.com qzonestyle.gtimg.cn as.alipayobjects.com ;style-src 'self' 'unsafe-inline' *.jianshu.io api.geetest.com static.geetest.com ;
ETag: W/"47a1d42ea1c6321456d016d9de9f7fef"
Cache-Control: max-age=0, private, must-revalidate
Set-Cookie: signin_redirect=http%3A%2F%2Fwww.jianshu.com%2F; path=/
Set-Cookie: _maleskine_session=MTFVK3ltcVZjNm1vb3dNMmZUUTJJTHVzYWZQaUIvZFNHYnVDWDMzMVdDUVc3dTA3dFpzUGFBUEdPeDRxYk1uQnBTVklOV1RyUFc5bVhhRkxVcS9ySVNEWDgxYTdHQVQ3S2tlaXc0OHNaSWlRa2NrUmRTZC9TZ0tPMGdVOGtIUXhwcnRJWFN0RFgwamFFL1F2S2FoMjQzRmc1ajNYa3RsbERuYnBZQmtKUmtodExaWW5FanRqL2cwRVU1YnN4SUgzN3FFVmdDTzJXK1BJTWN4RW5zZW1wVkxUUGtodTM5bE5zdU9JRDB1aloycUlWNUdieUlnTjVsQkhGSUVzY3Rrai0ta1VEU2xIeDVkK0pDaUdmRXgwWjdWdz09--12010d79a64cb1ee427931e7d7fe04bee742ff52; path=/; HttpOnly
X-Request-Id: 6cbfffbb-d112-45b2-81b5-fbdfa73d9e41
X-Runtime: 0.010188
X-Via: 1.1 wj29:1 (Cdn Cache Server V2.0), 1.1 zhouwtong132:2 (Cdn Cache Server V2.0)
Connection: close
  • 响应体

响应体里包含响应的实际数据。响应体的数据类型总称为MIME type,每个值包括一级类型和二级类型,之间用斜杠分隔。下面是一些常见的MIME type:

响应内容
text/plain
text/html
text/css
image/jpeg
image/png
image/svg+xml
audio/mp4
video/mp4
application/javascript
application/pdf
application/zip
application/atom+xml

以下是的响应报文,响应体为 text/html :

HTTP协议详解_第4张图片
响应体.png


HTTP首部字段

HTTP首部字段上面已经提到过,以下是 HTTP1.1 支持的各种字段,主要分为四种:1、通用首部字段;2、请求首部字段;3、响应首部字段;4、实体首部字段。

1、通用首部字段,即请求报文和响应报文都可以使用的字段,以下是通用字段表:

字段名 说明
Cache-Control 控制缓存行为
Connection 逐跳首部、连接的管理
Date 创建报文的日期时间
Pragma 报文指令
Trailer 报文末端的首部一览
Transfer-Encoding 指定报文主体的传输编码方式
Upgrade 升级为其他协议
Warning 错误通知
Via 代理服务器的相关信息

2、请求首部字段,即请求报文可以使用的字段,以下是请求报文字段表:

字段名 说明
Accept 用户代理可处理的媒体类型
Accept-Charset 优先的字符集
Accept-Encoding 优先的内容编码
Accept-Language 优先的语言(自然语言)
Authorizabon Web认证信息
Expect 期待服务器的特定行为
From 用户的电子邮箱地址
Host 请求资源所在服务器
If-Match 比较实体标记(ETag )
If-Modified-Since 比较资源的更新时间
If-None-Match 比较实体标记(与If-Match相反 )
lf-Range 资源未更新时发送实体Byte的范围请求
If-Unmodified-Since 比较资源的更新时间( 与If-Modified-Since 相反I
Max-Forwards 最大传输逐跳数
Proxy-Authorization 代理服务器要求客户端的认证信息
Range 实体的字节范围请求
Referer 对请求中URl的原始获取方
TE 传输编码的优先级
User-Agent HTTP客户端程序的信息

3、响应首部字段,即响应报文可以使用的字段,以下是响应报文字段表:

字段名 说明
Accept-Ranges 是否接受字节范围请求
Age 推算资源创建经过时间
ETag 资源的匹配信息
Location 令客户端重定向至指定URI
Proxy-Authenticate 代理服务器对客户端的认证信息
Retry-After 对再次发起请求的时机要求
Server HTTP服务器的安装信息
Vary 代理服务器缓存的管理信息
WWW-Authenticate 服务器对客户端的认证信息

3、实体首部字段,即针对请求报文和响应报文的实体部分使用的首部,主要是补充了实体资源相关信息,以下是实体首部字段表:

字段名 说明
Allow 资源可支持的HTTP方法
Content-Encoding 实体主体适用的编码方式
Content-Language 实体主体的自然语言
Content-Length 实体主体的大小(单位字节)
Content-Location 替代对应资源的URI
Content-MD5 实体主体的报文摘要
Content-Range 实体主体的位置范围
Content-Type 实体主体的媒体类型
Expires 实体主体过期的日期时间
Last-Modified 资源的最后修改日期时间


(待续)

你可能感兴趣的:(HTTP协议详解)