这是我参与「第四届青训营 」笔记创作活动的第6天
初始HTTP
例子引入: 输入URL到展现页面的全过程
浏览器进程:处理输入信息
浏览器内核:向服务器发送请求-->读取响应-->渲染--->页面加载完成(浏览器进程)
阶段一:用户输入阶段
用户在地址栏输入内容之后,浏览器会首先判断用户输入的是合法的URL还是搜索内容,如果是搜索内容就合成URL,如果是合法的URL就开始进行加载。
阶段二:发起URL请求阶段
构建请求行:浏览器进程首先会构建请求行信息,然后通过进程间通信IPC将URL请求发送给网络进程。
查找缓存:网络进程获取到URL之后,会先去本地缓存中查找是否有缓存资源,如果有则直接将缓存资源返回给浏览器进程,否则进入网络请求阶段。
DNS解析:网络进程请求首先会从DNS数据缓存服务器中查找是否缓存过当前域名的信息,有则直接返回,否则,会进行DNS解析域名对应的IP和端口号。
等待TCP队列:chrome有个机制,同一个域名同时最多只能建立6个TCP连接,如果超过这个数量的连接必须要进入排队等待状态。
建立TCP连接:通过TCP三次握手与服务器建立连接,然后进行数据传输。
发起HTTP请求:浏览器首先会向服务器发送请求行,请求行中包含了请求方法、请求URI和HTTP版本,还会发送请求头,告诉服务器一些浏览器的相关信息,比如浏览器内核、请求域名、Cookie等信息。
服务器处理请求:服务器首先返回相应行,包括协议版本和状态码,然后会返回响应头包含返回的数据类型,服务器要在客户端保存的Cookie等。
断开TCP连接:数据传输完成后,通过四次挥手来断开连接。
阶段三:准备渲染进程阶段
网络进程将获取的数据进行解析,根据响应头中的Content-type来判断响应数据的类型,如果是字节流类型,就将该请求交给下载管理器去下载,如果是text/html类型,就通知浏览器进程获取到的是HTML,准备渲染进程。
一般情况下浏览器的一个tab页面对应一个渲染进程,如果从当前页面打开的新页面并且属于同一站点,这种情况会复用渲染进程,其他情况则需要创建新的渲染进程。
阶段四:提交文档阶段
渲染进程准备好之后,浏览器会发出提交文档的消息给渲染进程,渲染进程收到消息后,会和网络进程建立数据传输的管道,文档数据传输完成后,渲染进程会返回确认提交的消息给浏览器进程。
浏览器收到确认提交的消息后,会更新浏览器的页面状态,包括了安全状态,地址栏的URL,前进后退的历史状态,并更新web页面为空白。
阶段五:页面渲染阶段
文档提交之后,渲染进程将开始页面解析并加载子资源。
构建DOM树:HTML经过解析后输出的是一个以document为顶层节点的树状结构的DOM。
样式计算:将从link标签引入的外部样式,style标签里的样式和元素身上的样式转换成浏览器能够理解的样式表,然后将样式表中的属性值进行标准化,例如color:red转换为color的rgb形式,然后根据CSS的继承和层叠规则计算出DOM树种每个节点的具体样式。
布局阶段:会生成一棵只包含可见元素的布局树,然后根据布局树的每个节点计算出其具体位置和大小。
分层:对页面种的复杂效果例如3D转换,页面滚动或者z轴排序等生成图层树。
绘制:为每个图层生成绘制列表,并将其提交到合成线程中。
光栅化:优先选择可视窗口内的图块来生成位图数据。
合成:所有图块都被光栅话之后开始显示页面。
什么是HTTP
HTTP 是超文本传输协议,它定义了客户端和服务器之间交换报文的格式和方式,默认使用 80 端口。它使用 TCP 作为传输层协议,保证了数据传输的可靠性。
请求头
响应头
HTTP协议具有以下优点:
- 支持客户端/服务器模式
- 简单快速:客户向服务器请求服务时,只需传送请求方法和路径。由于 HTTP 协议简单,使得 HTTP 服务器的程序规模小,因而通信速度很快。
- 无连接:无连接就是限制每次连接只处理一个请求。服务器处理完客户的请求,并收到客户的应答后,即断开连接,采用这种方式可以节省传输时间。
- 无状态:HTTP 协议是无状态协议,这里的状态是指通信过程的上下文信息。缺少状态意味着如果后续处理需要前面的信息,则它必须重传,这样可能会导致每次连接传送的数据量增大。另一方面,在服务器不需要先前信息时它的应答就比较快。
- 灵活:HTTP 允许传输任意类型的数据对象。正在传输的类型由 Content-Type 加以标记。
HTTP协议具有以下缺点:
- 无状态: HTTP 是一个无状态的协议,HTTP 服务器不会保存关于客户的任何信息。
- 明文传输: 协议中的报文使用的是文本形式,这就直接暴露给外界,不安全。
- 不安全
(1)通信使用明文(不加密),内容可能会被窃听;
(2)不验证通信方的身份,因此有可能遭遇伪装;
(3)无法证明报文的完整性,所以有可能已遭篡改;
协议分析
发展
HTTP 1.1 和 HTTP 2.0 的区别
- 二进制协议:HTTP2.0 是一个二进制协议。在 HTTP1.1 版中,报文的头信息必须是文本(ASCII 编码),数据体可以是文本,也可以是二进制。HTTP2.0则是一个彻底的二进制协议,头信息和数据体都是二进制,并且统称为"帧",可以分为头信息帧和数据帧。 帧的概念是它实现多路复用的基础。
- 多路复用: HTTP2.0 实现了多路复用,HTTP2.0 仍然复用 TCP 连接,但是在一个连接里,客户端和服务器都可以同时发送多个请求或回应,而且不用按照顺序一一发送,这样就避免了"队头堵塞"的问题。
- 数据流: HTTP2.0使用了数据流的概念,因为 HTTP2.0 的数据包是不按顺序发送的,同一个连接里面连续的数据包,可能属于不同的请求。因此,必须要对数据包做标记,指出它属于哪个请求。HTTP2.0 将每个请求或回应的所有数据包,称为一个数据流。每个数据流都有一个独一无二的编号。数据包发送时,都必须标记数据流 ID ,用来区分它属于哪个数据流。
- 头信息压缩: HTTP2.0 实现了头信息压缩,由于 HTTP 1.1 协议不带状态,每次请求都必须附上所有信息。所以,请求的很多字段都是重复的,比如 Cookie 和 User Agent ,一模一样的内容,每次请求都必须附带,这会浪费很多带宽,也影响速度。HTTP2.0 对这一点做了优化,引入了头信息压缩机制。一方面,头信息使用 gzip 或 compress 压缩后再发送;另一方面,客户端和服务器同时维护一张头信息表,所有字段都会存入这个表,生成一个索引号,以后就不发送同样字段了,只发送索引号,这样就能提高速度了。
- 服务器推送: HTTP2.0 允许服务器未经请求,主动向客户端发送资源,这叫做服务器推送。使用服务器推送提前给客户端推送必要的资源,这样就可以相对减少一些延迟时间。这里需要注意的是 HTTP2.0 下服务器主动推送的是静态资源,和 WebSocket 以及使用 SSE 等方式向客户端发送即时数据的推送是不同的。
HTTPS
HTTPS是以安全为目标的HTTP通道,简单讲是HTTP的安全版,即HTTP下加入SSL层,HTTPS的安全基础是SSL,因此加密的详细内容就需要SSL。
HTTPS的通信过程如下
-
客户端向服务器发起请求,请求中包含使用的协议版本号、生成的一个随机数、以及客户端支持的加密方法。
-
服务器端接收到请求后,确认双方使用的加密方法、并给出服务器的证书、以及一个服务器生成的随机数。
-
客户端确认服务器证书有效后,生成一个新的随机数,并使用数字证书中的公钥,加密这个随机数(预主密钥) ,然后发给服 务器。并且还会提供一个前面所有内容的 hash 的值,用来供服务器检验。
-
服务器使用自己的私钥,来解密客户端发送过来的随机数。并提供前面所有内容的 hash 值来供客户端检验。
-
客户端和服务器端根据约定的加密方法使用前面的三个随机数,生成对话秘钥,以后的对话过程都使用这个秘钥来加密信息。(对称加密)
报文
常见Method介绍
| 方法 | 介绍 |
|---|---|
| GET | 请求一个指定资源的表示形式,使用GET的请求应该只被用于获取数据 |
| POST | 用于将实体提交到指定的资源,通常导致在服务器上的状态变化或副作用 |
| PUT | 用请求有效载荷替换目标的所有当前表示 |
| DELETE | 删除指定资源 |
| HEAD | 请求一个与GET请求的相应相同的相应,但没有响应体 |
| CONNECT | 建立一个到由目标资源标识的服务器隧道 |
| OPTIONS | 用于描述目标资源的通信选项 |
| TRACE | 沿着到目标资源的路径执行一个消息环回测试(一般用来做测试) |
| PATCH | 用于对资源应用部分修改 |
safe:不会修改服务器的数据的方法 GET HEAD OPTIONS
Idempotent(幂等):同样的请求被执行一次与连续执行多次的效果是一样的,服务器的状态也是一样的,所有safe的方法都是幂等的 GET HEAD OPTIONS PUT DELETE
状态码
(1)2XX 成功
- 200 OK,表示从客户端发来的请求在服务器端被正确处理
- 204 No content,表示请求成功,但响应报文不含实体的主体部分
- 205 Reset Content,表示请求成功,但响应报文不含实体的主体部分,但是与 204 响应不同在于要求请求方重置内容
- 206 Partial Content,进行范围请求
(2)3XX 重定向
- 301 moved permanently,永久性重定向,表示资源已被分配了新的 URL
- 302 found,临时性重定向,表示资源临时被分配了新的 URL
- 303 see other,表示资源存在着另一个 URL,应使用 GET 方法获取资源
- 304 not modified,表示服务器允许访问资源,但因发生请求未满足条件的情况
- 307 temporary redirect,临时重定向,和302含义类似,但是期望客户端保持请求方法不变向新的地址发出请求
(3)4XX 客户端错误
- 400 bad request,请求报文存在语法错误
- 401 unauthorized,表示发送的请求需要有通过 HTTP 认证的认证信息
- 403 forbidden,表示对请求资源的访问被服务器拒绝
- 404 not found,表示在服务器上没有找到请求的资源
(4)5XX 服务器错误
- 500 internal sever error,表示服务器端在执行请求时发生了错误
- 501 Not Implemented,表示服务器不支持当前请求所需要的某个功能
- 503 service unavailable,表明服务器暂时处于超负载或正在停机维护,无法处理请求
常用请求头和响应头
常用请求头
常用响应头
强缓存和协商缓存
- 浏览器在第一次加载资源时,服务器返回200,浏览器从服务器下载资源,并缓存资源文件与响应头。
- 下一次加载资源的时候,由于强缓存的优先级更高。所以浏览器会先比较当前时间与上一次返回200时的时间差,也就是看有没有超过
Cache-Control中的max-age。如果没有过期,则命中强缓存,直接从浏览器读取资源。如果浏览器不支持HTTP1.1,则需要根据Expires头(指定过期时间)来判断是否过期 - 如果资源已经过期,则说明强缓存没有命中,下一步开始协商缓存。如果上一次响应头中含有
Etag,则发送带有If-None-Match的请求,Etag值一致则说明没有修改,命中协商缓存,服务器返回304,从浏览器读取资源。如果不一致则返回新的资源文件带上新的Etag和200。 - 如果上一次的响应头中没有Etag,则发送带有If-Modified-Since的请求,比较文件最后修改时间(Last-Modified)一致则说明没有修改,命中协商缓存,服务器返回304,从浏览器读取资源。如果不一致则返回新的资源文件带上新的Etag和200。
Etag与Last-Modified的各自缺点?
大型网站多使用负载分担的方式来调度HTTP请求。不同的服务器,在其它所有方面都一样的情况下,对于同一页面也能够计算出不同的ETag;ETag的计算占用服务器的CPU资源。
Last-Modified标注最后修改时间只能精确到秒级,如果某些文件在一秒钟内被修改多次,文件已经改变但是Last-Modified却没有变,这样会造成缓存命中的不准确。
cookie
Set-Cookie-response