HTTP 相关
一、HTTP/0.9
背景
1991 年提出的 HTTP/0.9,当时主要用于学术交流,需求很简单——用于在网络间传递 HTML 超文本的内容,所以被称为超文本传输协议。
HTTP/0.9 的请求流程
1、因为 HTTP 都是基于 TCP 协议的,所以客户端先要根据 IP 地址、端口号去和服务器建立连接,建立连接的过程就是 TCP 协议三次握手的过程。
2、建立好连接后,会发送一个 GET 请求行的信息,如 GET /index.html 用来获取 index.html。
3、服务器接收到请求信息后,读取对应的 HTML 文件,并将数据以 ASCII 字符流返回给客户端。
4、服务器发送完成后,断开 HTTP 连接。
HTTP/0.9 的主要特点
1、只有请求行,没有请求头和请求体。
2、服务器也不会返回头信息,只会返回数据。
3、服务器返回的数据是以 ASCII 字符流来传输的,因为都是 HTML 格式的文件,所以用 ASCII 字节码来传输是最合适的。
二、HTTP/1.0
HTTP/1.0 的主要特点
1、HTTP1.0 引入了请求头和响应头支持传输多种类型的文件。
2、HTTP1.0 引入了状态码,User-Agent 请求头字段也是 1.0 加入的。还引入了 POST 和 HEAD 方法。
状态码是通过响应行的方式来通知浏览器的。User-Agent 请求头可以统计客户端的基础信息,比如 Windows 和 macOS 的用户数量分别是多少等。
3、为了减轻服务器的压力,在 HTTP/1.0 中提供了 Cache 机制,用来缓存已经下载过的数据。
4、HTTP/1.0 每次进行一次 HTTP 通信都要经历建立 TCP 连接、传输 HTTP 数据、断开 TCP 连接三个阶段。重复的步骤会浪费好多时间。(缺点)
三、HTTP/1.1
持久连接
它的特点是在一个 TCP 连接上可以传输多个 HTTP 请求,只要浏览器或者服务器没有明确断开连接,那么该 TCP 连接会一直保持。HTTP 的持久连接可以有效减少 TCP 建立连接和断开连接的次数,这样的好处是减少了服务器额外的负担,并提升整体 HTTP 的请求时长。 持久连接在 HTTP/1.1 中是默认开启的,所以你不需要专门为了持久连接去 HTTP 请求头设置信息,如果你不想要采用持久连接,可以在 HTTP 请求头中加上 Connection: close。目前
队头阻塞与不成熟的 HTTP 管线化
虽然 HTTP/1.1 增加了持久连接的能力,减少了 TCP 连接和断开的次数,但是它还是要等待前一个 HTTP 请求返回之后才能进行下一个 HTTP 请求。想象一下如果某个 HTTP 请求因为某些原因没有及时返回,那么这个请求之后的所有 HTTP 请求都会被堵住,这就是常说的问题。
HTTP/1.1 试图通过管线化的技术来解决队头阻塞的问题。HTTP/1.1 中的管线化是指将多个 HTTP 请求整批提交给服务器的技术,虽然可以整批发送请求,不过服务器依然需要根据请求顺序来回复浏览器的请求。
域名分片
在 HTTP/1.0 中,每个域名都绑定了一个唯一的 IP 地址,因此一个服务器只能为一个域名服务。随着虚拟主机技术的发展,实现了在一台物理主机上绑定多个虚拟主机,每个虚拟主机对应一个单独的域名,这些域名共用一个 IP 地址。因此,
Chunk transfer 机制
在设计 HTTP/1.0 时,需要在响应头中设置完整的数据大小,如 Content-Length: 901,这样浏览器就可以根据设置的数据大小来接收数据。不过随着服务器端的技术发展,很多页面的内容都是动态生成的,因此在传输数据之前并不知道最终的数据大小,这就导致了浏览器不知道何时会接收完所有的文件数据。
HTTP/1.1 通过引入 Chunk transfer 机制来解决这个问题,服务器会将数据分割成若干个任意大小的数据块,每个数据块发送时会附上上个数据块的长度,最后使用一个零长度的块作为发送数据完成的标志。这样就提供了对动态内容的支持。
- 5、新增方法:PUT、 PATCH、 OPTIONS、 DELETE。
四、HTTP/2.0
多路复用机制
HTTP/1.1 对带宽的利用率并不理想,原因主要有三个。
- TCP 的慢启动机制
- 多个 TCP 连接竞争带宽资源
- HTTP/1.1 队头阻塞的问题
HTTP/2.0 的解决方案:多路复用机制(通过引入了二进制分帧层实现)
- 首先,浏览器准备好请求数据,包括了请求行、请求头等信息,如果是 POST 方法,那么还要有请求体。
- 这些数据经过二进制分帧层处理之后,会被转换为一个个带有请求 ID 编号的帧,通过协议栈将这些帧发送给服务器。
- 服务器接收到所有帧之后,会将所有相同 ID 的帧合并为一条完整的请求信息。
- 然后服务器处理该条请求,并将处理的响应行、响应头和响应体分别发送至二进制分帧层。
- 同样,二进制分帧层会将这些响应数据转换为一个个带有请求 ID 编号的帧,经过协议栈发送给浏览器。
- 浏览器接收到响应帧之后,会根据 ID 编号将帧的数据提交给对应的请求。
头部压缩
无论是 HTTP/1.1 还是 HTTP/2,它们都有请求头和响应头,这是浏览器和服务器的通信语言。HTTP/2 对请求头和响应头进行了压缩。
HTTP 1.1 版本会出现 「User-Agent、Cookie、Accept、Server、Range」 等字段可能会占用几百甚至几千字节,而 Body 却经常只有几十字节,所以导致头部偏重。HTTP 2.0 使用 HPACK 算法对头部进行压缩,节省空间。
请求优先级
为了避免重要的请求得不到服务器的优先处理,HTTP/2 提供了请求优先级,可以设置请求的优先级。
服务器推送
除了设置请求优先级之外,HTTP/2.0 还可以直接将数据提前推送到浏览器。
场景
用户请求一个 HTML 页面之后,服务器知道该 HTML 页面会引用几个重要的 JavaScript 文件和 CSS 文件,那么在接收到 HTML 请求之后,附带将要使用的 CSS 文件和 JavaScript 文件一并发送给浏览器,这样当浏览器解析完 HTML 文件之后,就能直接拿到需要的 CSS 文件和 JavaScript 文件,这对首次打开页面的速度起到了至关重要的作用。
五、HTTP header 有哪些字段
六、HTTP 有哪些请求方法
GET 方法 请求一个指定资源的表示形式. 使用 GET 的请求应该只被用于获取数据。
HEAD 方法 请求一个与 GET 请求的响应相同的响应,但没有响应体。
HEAD 方法和 GET 方法差不多,都是发送请求并从服务器获取数据。但服务器并不会返回请求的实体数据,只会传回响应头,也就是资源的“元信息”。(幂等方法)
你也可以理解为 HEAD 方法是 GET 方法的简易版,它的响应头与 GET 完全相同。
一般可以用在很多并不真正需要资源的场景,避免传输 body 数据造成不必要的资源浪费。
举两个例子:
1、检查一个文件是否存在可以用 HEAD 请求,没有必要用 GET 把整个文件都取下来。
2、检查文件是否有最新版本,也可以使用 HEAD,服务器会在响应头里把文件的修改时间传回来。
POST 方法 用于将实体提交到指定的资源,通常导致在服务器上的状态变化或副作用。
PUT 方法 用请求有效载荷替换目标资源的所有当前表示。
DELETE 方法 删除指定的资源。
CONNECT 方法 建立一个到由目标资源标识的服务器的隧道。
OPTIONS 方法 用于描述目标资源的通信选项。
TRACE 方法 沿着到目标资源的路径执行一个消息环回测试。
PATCH 方法 用于对资源应用部分修改。
七、何谓简单请求
一个 HTTP 请求如果满足以下所有要求,则该请求为简单请求(跨域不会发预检请求)。
1、使用下列方法之一:
GETHEADPOST
2、除了被用户代理自动设置的首部字段(例如
Connection,User-Agent)之外,只能是以下首部字段:Accept: 请求头用来告知(服务器)客户端可以处理的内容类型。Accept-Language: 请求头允许客户端声明它可以理解的自然语言,以及优先选择的区域方言。Content-Language: 用来说明访问者希望采用的语言或语言组合,这样的话用户就可以根据自己偏好的语言来定制不同的内容。Content-Type: 实体头部用于指示资源的 MIME 类型。
3、
Content-Type的值仅限于下列三者之一:text/plainmultipart/form-dataapplication/x-www-form-urlencoded
russ