
什么是HTTP?
HTTP是TCP/IP基于应用层的通信协议,用于标准化客户端和服务端之间的通信方式。它定义了如何请求和传输内容。默认TCP端口为80,当然也可以使用其他端口。(HTTPS的默认端口为443)
HTTP/0.9
1991年,提出了HTTP的第一个版本HTTP/0.9。它是有史以来最简单的协议。只有一个GET方法。如果客户端像服务端请求一个网页,将会发出如下简单的请求:
客户端请求:
GET /index.html
服务器响应:
(response only)
(connection closed)
如上,服务器获取到请求,将HTML响应作为请求,一旦内容传输完,连接将被关闭。
总结:
- 没有请求头
- 只有一个
GET方法 - 响应必须是HTML
HTTP/1.0
1996年,HTTP/1.0被提出,与HTTP/0.9有了很大的改进。
与HTTP/0.9仅针对HTML响应设计的不同,HTTP/1.0可以处理其他响应格式,如图像,视频文件,纯文本和任何其他内容类型。并且添加了POST和HEAD方法,更改了请求和响应格式,在请求和响应都添加了HTTP请求头,添加了状态码和表示响应,引入字符集,multi-part类型,授权,缓存,内容编码等。
HTTP/1.0 请求如下:
GET / HTTP/1.0
Host: dpplh.com
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.117 Safari/537.36
Accept: */*
综上,除了请求以外,还发送了客户端信息和所接受的响应类型。
响应如下:
HTTP/1.0 200 OK
Content-Type: text/plain
Content-Length: 137582
Expires: Mon, 04 Jan 2021 06:54:02 GMT
Last-Modified: Sat, 04 Jan 2020 01:50:20 GMT
Server: sffe
(response body)
(connection closed)
在响应最开始有HTTP/1.0(HTTP,后接版本号),然后是状态码
在此叫新版本中,请求和响应头仍保持ASCII编码状态,但是响应主体可以是任何类型,即图像,视频,HTML,纯文本和其他任何内容类型。因此,现在服务器可以将任何内容类型发送到客户端。
HTTP/1.0主要缺点之一就是每个连接不能有多个请求。也就是每当客户端需要服务器中的某些内容,都必须开启新的TCP连接,并且在满足单个请求之后,连接被关闭。对于任何下一个请求,都必须建立在新连接上。每次的TCP连接都需要三次握手,会有严重的性能问题。
某些在HTTP/1.0 尝试通过引入一个新的标头,
Connection: keep-alive,用来告诉服务器不要关闭连接,但是并没有得到广泛支持,问题仍然存在。
HTTP除了无连接之外,还是一种无状态协议,即服务器不维护有关的客户端信息,因此每个连接都必须含有服务器所需要的客户端信息,并且不与之前任何一个旧的请求有关联。因此除了客户端必须建立大量连接之外,还需要在请求过程中发送一些冗余的数据,增加了带宽的占用。
HTTP/1.1
1999年,仅过了三年,HTTP/1.1就发布了,在HTTP/1.0的基础上做了很多的改进。
-
新的HTTP请求方法:PUT、PATCH、OPTIONS、DELETE
-
Host主机名标识,在HTTP/1.0不是必须的,但在HTTP/1.1变成必须的
-
持久连接,在HTTP/1.0每个连接中只有一个请求,并且一旦没出请求,连接就会被关闭,这会导致性能下降和延迟问题。HTTP/1.0加入了持久连接,即默认情况下未关闭连接并且保持打开状态,从而允许多个顺序请求。如果要关闭连接,
Connection: close。客户端通常在最后一个请求中发送此标头,以安全关闭连接。 -
流水线化:客户端可以向服务器发送多个请求,而不必等待来自同一个连接上的服务器响应,并且服务器必须保持接收请求的相同顺序发送响应。
在流水线化中,客户端怎么知道第一个响应下载完成且下一个响应内容开始? 此时必须提供
Content-Length标头,客户端可以使用该标头来标识响应的结束位置,并且可以开始等待下一个响应。
疑问:如果数据是动态的并且服务器无法预知内容长度,该怎么办呢?
为了解决这个问题,HTTP/1.1引入了分块编码。在这种情况下,服务器可能会省略Content-Length,而推荐使用分块编码。但是,如果他们都不可用,则必须在请求结束时关闭连接。
分块传输如果是动态内容,则当服务器无法真正确定Content-Length传输开始的时间时,它可能会开始分块发送内容,并在Content-Length发送时为每个块添加内容,并且当前所有块都以发送(即整个传输已完成)时,它会发送一个空块(Content-Length即将设置为零),以表示传输以完成的客户端。为了通知客户端分块传输的信息,服务器需包含标头Transfer-Encoding: chunked- 与HTTP/1.0仅具有基本身份验证的情况不同,HTTP/1.1包括摘要身份验证和代理身份验证
- 缓存
- Byte Range
- 字符集
- 语言
- Cookie
- 更强的压缩支持
- 新的状态码
- ...
SPDY
SPDY是Google在2019年为了提高网络速度,并在降低网络延迟的同时提高网络安全性时提出的。这个协议在Chrome浏览器证明可行后,就被当作HTTP/2的基础,主要特性都在HTTP/2中被继承。
SPDY里的预置字典为头部特殊设计的,但它使用的仍然是DEFLATE算法,其中包括动态Huffman编码以及字符串匹配。但是因为DEFLATE算法使用的是落后的字符串匹配以及动态Huffman编码,攻击者可以从压缩头部提取密钥认证cookies,从而很容易进行犯罪行为。攻击者还可以控制部分请求头,并且修改部分请求来找回整个cookie以及观察到再压缩情况下请求改变的总大小。
HTTP/2.0
HTTP/2.0设计用于低延迟的内容传输,与HTTP/1.1的不同之处:
1. 二进制协议:头和数据体都是二进制
HTTP/2.0主要构件模块是帧和流,二进制协议易于解析,解决HTTP/1.x存在的延迟问题。
帧和流
HTTP消息由一个或者多个帧组成。有一个HEADERS用于元数据和帧DATA帧的有效载荷,并存在集中其他类型的帧(HEADERS,DATA,RST_STREAM,SETTINGS,PRIORITY...)。
每个HTTP/2.0请求和响应有一个唯一的ID,并将其划分为帧。每个帧即二进制数据,帧的集合为流,并且每个帧都有一个公共的头。
客户端发起的任何请求都是使用的奇数,服务端的响应具有偶数流ID
除了HEADERS和DATA,还有一种特殊的帧类型RST_STREAM,用于终止某些流,即客户端可以发送该帧让服务器知道不再需要该流。
HTTP/1.1中,服务器停止发送到客户端的响应被关闭,导致轻微的延迟。因为每个新的请求都需要重新连接。HTTP/2.0中,客户端使用RST_STREAM来通知服务器并停止接收特定的流,同时连接不断开,可以继续接收其他的流。
2. 多路复用:通过单个连接的多个异步HTTP请求
使用帧和流进行请求和响应,所以一旦打开TCP连接,所有流都将通过同一连接异步发送,无需额外的连接。相反,服务器以相同的异步方式进行响应,即响应没有顺序,客户端使用分配的流ID来表示特性数据所属的流,这样就解决了HTTP/1.x中存在的行头阻塞问题。
3. 使用HPack进行头部压缩
当我们不断的从客户端访问服务器时,会反复的发送大量的冗余数据,有时还可能会出现cookie,这回增加头部大小,导致带宽使用和延迟增加。
与请求和响应不同,标头不采用gzip和comparess的格式进行压缩,而是如下三种压缩方法:
- 静态字典:一个有着61个通用头部字段,并且部分字段是有预定义值的预定义字典。
- 动态字典:在连接中,一些列实际的头部会被添加进去。因为字典有限制大小,所以当新项被增加,旧项就会被移除。
- Huffman编码:一种可以被用来对任何字符串:Key or Value,进行编码的静态Huffman编码。这种编码方式专门为HTTP响应或者响应头设计的——ASCII里的数字和字母可以更短。
4. 服务器推送:单个请求多个响应
HTTP/2.0允许再客户端未经请求,主动向客户端发送资源。
5. 请求优先级
客户端在可以发送PRIORITY帧来更改流的优先级。如果没有优先级信息,则服务器异步处理请求,即没有任何顺序。如果分配了优先级,则服务器根据此优先级信息确定需要分配多少资源来处理哪个请求。
MIME Types
text/plain
text/html
image/jpeg
image/png
audio/mpeg
audio/ogg
audio/*
video/mp4
application/*
application/json
application/javascript
application/ecmascript
application/octet-stream
…
| 类型 | 描述 | 事例 |
|---|---|---|
| text | 普通文本 | text/plain, text/html, text/css, text/javascript |
| image | 图像;不包括视频,但是Gif也是用image类型 | image/gif, image/png, image/jpeg, image/bmp, image/webp, image/x-icon, image/vnd.microsoft.icon |
| audio | 音频文件 | audio/midi, audio/mpeg, audio/webm, audio/ogg, audio/wav |
| video | 视频文件 | video/webm, video/ogg |
| application | 二进制数据 | application/octet-stream, application/xhtml+xml, application/xml, application/pdf |
对于text类型的文件如果没有特定的subtype,默认使用text/plain。二进制文件没有特定或者已知的subtype,默认使用application/octet-stream
重点的MIME类型
1、 application/octet-stream
这是应用程序文件的默认值,意思是未知的应用程序文件,浏览器一般不会自动执行和询问执行。
2、 text/plain
文件的默认值,即使它意味着位置的文本文件,浏览器也可以直接展示。
3、 text/css
在网页中要被解析为css的任何css文件,都必须制定MIME为text/css。通常情况下浏览器不识别.css为后缀的文件MIME类型,而是将其以MIME为text/plain或application/octet-stream来发送给浏览器。
4、 text/html
所有的HTML内容都应该使用这种类型。XHTML的其他MIME类型(如application/xml+html)现在基本不使用。
5、 图片类型
| MIME类型 | 图片类型 |
|---|---|
| image/gif | GIF图片 |
| image/jpeg | JPEG图片 |
| image/png | PNG图片 |
| image/svg+xml | SVP图片(矢量图) |
6、 音视频类型
| MIME类型 | 音视频类型 |
|---|---|
| audio/wave audio/wav audio/x-wav audio/x-pn-wav |
音频流媒体文件,一般支持PCM编码 |
| audio/webm | WebM音频文件格式 |
| video/webm | 采用WebM视频文件格式的音频文件 |
| audio/ogg | 采用OGG多媒体文件格式的音频文件 |
| video/ogg application/ogg |
采用OGG多媒体文件格式的音视频文件 |