浏览器原理 28 # HTTP/1:HTTP性能优化
Posted 凯小默
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了浏览器原理 28 # HTTP/1:HTTP性能优化相关的知识,希望对你有一定的参考价值。
说明
浏览器工作原理与实践专栏学习笔记
超文本传输协议 HTTP/0.9
HTTP/0.9 是于 1991 年提出的,主要用于学术交流,需求很简单——用来在网络之间传递 html 超文本的内容,被称为超文本传输协议。
HTTP/0.9 请求流程
- 因为 HTTP 都是基于 TCP 协议的,所以客户端先要根据 IP 地址、端口和服务器建立 TCP 连接,而建立连接的过程就是 TCP 协议三次握手的过程。
- 建立好连接之后,会发送一个 GET 请求行的信息,如GET /index.html用来获取 index.html。
- 服务器接收请求信息之后,读取对应的 HTML 文件,并将数据以 ASCII 字符流返回给客户端。
- HTML 文档传输完成后,断开连接。
我们先看看:三次握手和四次挥手
参考文章:TCP为什么是三次握手和四次挥手
标志位含义
- SYN:发起一个新连接。
- ACK:确认序号有效。
- FIN:释放一个连接。
三次握手的过程
所谓三次握手,即:建立TCP连接,需要客户端和服务端总共发送至少三个包确认连接的建立。
流程如下:
第一次握手
Client什么都不能确认,Server确认了对方发送正常
- Client将标志位SYN置1,随机产生一个值seq=J,并将数据包发给Server
- Client进入SYN_SENT状态,等待Server确认
第二次握手
Client确认:自己发送/接收正常,对方发送/接收正常,Server确认:自己接收正常 ,对方发送正常
- Server收到数据包后标志位SYN=1知道Client请求建立连接,Server将标志位SYN和ACK都置1,随机产生一个值,并将数据包发给Client确认连接请求,Server进入SYN_RCVD状态
第三次握手
Client确认:自己发送/接收正常, 对方发送/接收正常,Server确认:自己发送/接收正常,对方发送/接收正常
- Client收到确认后若ACK为1,则将该数据包发送给Server,Server检查ACK为1则连接建立成功,Client与Server进入ESTABLISHED状态完成三次握手,可以传输数据
通过三次握手确认双方收发功能都正常,四次也可以但是显得比较多余。
三次握手主要是为了防止已失效的请求报文段突然又传送到了服务端而产生连接的误判。
四次挥手的过程
所谓四次挥手:即终止TCP连接,需要客户端和服务端总共发送4个包确认连接的断开。
流程如下:
第一次挥手:
- Client发送一个FIN,用来关闭Client到Server的数据传送,Client进入FIN_WAIT_1状态。
第二次挥手:
- Server收到FIN后,发送一个ACK给Client,Server进入CLOSE_WAIT状态。
第三次挥手:
- Server发送一个FIN,用来关闭Server到Client的数据传送,Server进入LAST_ACK状态。
第四次挥手:
- Client收到FIN后,Client进入TIME_WAIT状态,发送ACK给Server,Server进入CLOSED状态,完成四次握手。
HTTP/0.9 的三个特点
- 第一个是只有一个请求行,并没有 HTTP 请求头和请求体,因为只需要一个请求行就可以完整表达客户端的需求了。
- 第二个是服务器也没有返回头信息,这是因为服务器端并不需要告诉客户端太多信息,只需要返回数据就可以了。
- 第三个是返回的文件内容是以 ASCII 字符流来传输的,因为都是 HTML 格式的文件,所以使用 ASCII 字节码来传输是最合适的。
被浏览器推动的 HTTP/1.0
万维网的高速发展带来了很多新的需求,首先在浏览器中展示的不单是 HTML 文件了,还包括了 javascript、CSS、图片、音频、视频等不同类型的文件。
那么该如何实现多种类型文件的下载呢?
HTTP/1.0 引入了请求头和响应头,它们都是以为 Key-Value 形式保存的,在 HTTP 发送请求时,会带上请求头信息,服务器返回数据时,会先返回响应头信息。
HTTP/1.0 的请求流程
那 HTTP/1.0 是怎么通过请求头和响应头来支持多种不同类型的数据呢?
- 首先,浏览器需要知道服务器返回的数据是什么类型的,然后浏览器才能根据不同的数据类型做针对性的处理。
- 其次,由于万维网所支持的应用变得越来越广,所以单个文件的数据量也变得越来越大。为了减轻传输性能,服务器会对数据进行压缩后再传输,所以浏览器需要知道服务器压缩的方法。
- 再次,由于万维网是支持全球范围的,所以需要提供国际化的支持,服务器需要对不同的地区提供不同的语言版本,这就需要浏览器告诉服务器它想要什么语言版本的页面。
- 最后,由于增加了各种不同类型的文件,而每种文件的编码形式又可能不一样,为了能够准确地读取文件,浏览器需要知道文件的编码类型。
HTTP 请求头告诉服务器它期待服务器返回什么类型的文件、采取什么形式的压缩、提供什么语言的文件以及文件的具体编码。比如:
accept: text/html // 表示期望服务器返回 html 类型的文件
accept-encoding: gzip, deflate, br // 表示期望服务器可以采用 gzip、deflate 或者 br 其中的一种压缩方式
accept-Charset: ISO-8859-1,utf-8 // 表示期望返回的文件编码是 UTF-8 或者 ISO-8859-1
accept-language: zh-CN,zh // 表示期望页面的优先语言是中文
响应头的数据信息:
content-encoding: br // 表示服务器采用了 br 的压缩方法
content-type: text/html; charset=UTF-8 // 表示服务器返回的是 html 文件,并且该文件的编码类型是 UTF-8。
HTTP/1.0典型的特性
- 状态码:是通过响应行的方式来通知浏览器的。有的请求服务器可能无法处理,或者处理出错,这时候就需要告诉浏览器服务器最终处理该请求的情况,这就引入了状态码。
- Cache 机制:为了减轻服务器的压力,在 HTTP/1.0 中提供了 Cache 机制,用来缓存已经下载过的数据。
- 用户代理:服务器需要统计客户端的基础信息,比如 Windows 和 macOS 的用户数量分别是多少,所以 HTTP/1.0 的请求头中还加入了用户代理的字段。
缝缝补补的 HTTP/1.1
1. 改进持久连接
HTTP/1.0 的短连接:
HTTP/1.0 的持久连接:
有效减少 TCP 建立连接和断开连接的次数,这样的好处是减少了服务器额外的负担,并提升整体 HTTP 的请求时长。
HTTP/1.1 中增加了持久连接的方法,它的特点是在一个 TCP 连接上可以传输多个 HTTP 请求,只要浏览器或者服务器没有明确断开连接,那么该 TCP 连接会一直保持。
如果你不想要采用持久连接,可以在 HTTP 请求头中加上
Connection: close
。目前浏览器中对于同一个域名,默认允许同时建立 6 个 TCP 持久连接。http/1.1 中的一个 tcp 链接同时只能发起一个http请求!浏览器会让每个域名同时最多建立 6 个 tcp 链接,也就是说同一个域名同时能支持 6 个 http 请求!
2. 不成熟的 HTTP 管线化
队头阻塞
持久连接虽然能减少 TCP 的建立和断开次数,但是它需要等待前面的请求返回之后,才能进行下一次请求。如果 TCP 通道中的某个请求因为某些原因没有及时返回,那么就会阻塞后面的所有请求。
HTTP/1.1 中的管线化
指将多个 HTTP 请求整批提交给服务器的技术,虽然可以整批发送请求,不过服务器依然需要根据请求顺序来回复浏览器的请求。
3. 提供虚拟主机的支持
在 HTTP/1.0 中,每个域名绑定了一个唯一的 IP 地址,因此一个服务器只能支持一个域名。
但是随着虚拟主机技术的发展,需要实现在一台物理主机上绑定多个虚拟主机,每个虚拟主机都有自己的单独的域名,这些单独的域名都公用同一个 IP 地址。
因此,HTTP/1.1 的请求头中增加了 Host 字段,用来表示当前的域名地址,这样服务器就可以根据不同的 Host 值做不同的处理。
4. 对动态生成的内容提供了完美支持
在设计 HTTP/1.0 时,需要在响应头中设置完整的数据大小,如 Content-Length: 901
,这样浏览器就可以根据设置的数据大小来接收数据。
不过随着服务器端的技术发展,很多页面的内容都是动态生成的,因此在传输数据之前并不知道最终的数据大小,这就导致了浏览器不知道何时会接收完所有的文件数据。
HTTP/1.1 通过引入 Chunk transfer 机制来解决这个问题,服务器会将数据分割成若干个任意大小的数据块,每个数据块发送时会附上上个数据块的长度,最后使用一个零长度的块作为发送数据完成的标志。这样就提供了对动态内容的支持。
5. 客户端 Cookie、安全机制
Cookie 机制:可以看看之前的文章:浏览器原理 03 # HTTP 请求流程:为什么很多站点第二次打开速度会很快?
安全机制后面的文章会涉及。
以上是关于浏览器原理 28 # HTTP/1:HTTP性能优化的主要内容,如果未能解决你的问题,请参考以下文章