持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第12天,点击查看活动详情
事先声明:本篇文章来自 winter 的《重学前端》 ,因为讲得很好,记录笔记方便之后翻阅。
对浏览器的实现者来说,他们做的事情,就是把一个 URL 变成一个屏幕上显示的网页。
这个过程是这样的:
- 浏览器首先使用 HTTP 协议或者 HTTPS 协议,向服务端请求页面;
- 把请求回来的 HTML 代码经过解析,构建成 DOM 树;
- 计算 DOM 树上的 CSS 属性;
- 最后根据 CSS 属性对元素逐个进行渲染,得到内存中的位图;
- 一个可选的步骤是对位图进行合成,这会极大地增加后续绘制的速度;
- 合成之后,再绘制到界面上。
从 HTTP 请求响应开始,这个过程并非是上一步做完才开始做下一步,而是像一条流水线似的工作。
从 HTTP 请求回来,就产生了流式的数据,后续的 DOM 树构建、CSS 计算、渲染、合成、绘制,都是尽可能地流式处理前一步的产出:即不需要等到上一步骤完全结束,就开始处理上一步的输出,这样我们在浏览网页时,才会看到逐步出现的页面。
网络通讯
HTTP 协议
浏览器首先要做的事就是根据 URL 把数据取回来,取回数据使用的是 HTTP 协议,实际上这个过程之前还有 DNS 查询(因为我们通常在浏览器地址栏输入的是域名,这时候需要根据域名获取目标网址的 IP 地址,就用到了 DNS 解析,具体可以查看 这篇文章)
了解 HTTP 协议
HTTP 协议是基于 TCP 协议出现的,对 TCP 协议来说,TCP 协议是一条双向的通讯通道,HTTP 在 TCP 的基础上,规定了 Request-Response 的模式。这个模式决定了通讯必定是由浏览器端首先发起的。
一次完整的 HTTP 请求,会有请求和响应两部分。
在请求部分,第一行被称作 request line,它分为三个部分,HTTP Method,也就是请求的“方法”,请求的路径和请求的协议和版本。
在响应部分,第一行被称作 response line,它也分为三个部分,协议和版本、状态码和状态文本。
紧随在 request line 或者 response line 之后,是请求头 / 响应头,这些头由若干行组成,每行是用冒号分隔的名称和值。
在头之后,以一个空行(两个换行符)为分隔,是请求体 / 响应体,请求体可能包含文件或者表单数据,响应体则是 HTML 代码。
因此 HTTP 协议可以划分为如下部分:
下面来具体看看每个部分分别是什么。
HTTP Method(方法)
首先是 request line
里面的方法部分,表示我们此次 HTTP 请求希望执行的操作类型。方法有以下几种定义:
- GET
- POST
- HEAD
- PUT
- DELETE
- CONNECT
- OPTIONS
- TRACE
浏览器通过地址栏访问页面都是 GET
方法。表单提交产生 POST
方法。
HEAD
则是跟 GET
类似,只返回响应头,多数由 JavaScript 发起。
PUT
和 DELETE
分别表示添加资源和删除资源,但是实际上这只是语义上的一种约定,并没有强约束。
CONNECT
现在多用于 HTTPS 和 WebSocket。
OPTIONS
和 TRACE
一般用于调试,多数线上服务都不支持。
HTTP Status code(状态码)和 Status text(状态文本)
接下来我们看看 response line
的状态码和状态文本。常见的状态码有以下几种。
- 1xx:临时回应,表示客户端请继续。
- 2xx:请求成功。200:请求成功。
- 3xx: 表示请求的目标有变化,希望客户端进一步处理。
- 301&302:永久性与临时性跳转。
- 304:跟客户端缓存没有更新。
- 4xx:客户端请求错误。
- 403:无权限。
- 404:表示请求的页面不存在。
- 418:It’s a teapot. 这是一个彩蛋,来自 ietf 的一个愚人节玩笑。(超文本咖啡壶控制协议)
- 5xx:服务端请求错误。500:服务端错误。
- 503:服务端暂时性错误,可以一会再试。
HTTP Head (HTTP 头)
在 HTTP 标准中,有完整的请求 / 响应头规定,这里我们挑几个重点的说一下:
接下来看一下 Response Header。
HTTP Request Body
HTTP 请求的 body 主要用于提交表单场景。实际上,HTTP 请求的 body 是比较自由的,只要浏览器端发送的 body 服务端认可就可以了。一些常见的 body 格式是:
application/json
application/x-www-form-urlencoded
multipart/form-data
text/xml
我们使用 HTML 的 form 标签提交产生的 HTML 请求,默认会产生 application/x-www-form-urlencoded
的数据格式,当有文件上传时,则会使用 multipart/form-data
。
HTTPS
在 HTTP 协议的基础上,HTTPS 和 HTTP2 规定了更复杂的内容,但是它基本保持了 HTTP 的设计思想,即:使用上的 Request-Response 模式。
HTTPS 有两个作用:
- 确定请求的目标服务端身份
- 保证传输的数据不会被网络中间节点窃听或者篡改。
HTTPS 是使用加密通道来传输 HTTP 的内容。但是 HTTPS 首先与服务端建立一条 TLS 加密通道。TLS 构建于 TCP 协议之上,它实际上是对传输的内容做一次加密,所以从传输内容上看,HTTPS 跟 HTTP 没有任何区别。
HTTP2
HTTP 2.0 最大的改进有两点:
- 一是支持服务端推送
- 二是支持 TCP 连接复用
服务端推送能够在客户端发送第一个请求到服务端时,提前把一部分内容推送给客户端,放入缓存当中,这可以避免客户端请求顺序带来的并行度不高,从而导致的性能问题。
TCP 连接复用,则使用同一个 TCP 连接来传输多个 HTTP 请求,避免了 TCP 连接建立时的三次握手开销,和初建 TCP 连接时传输窗口小的问题。
Note: 其实很多优化涉及更下层的协议。IP 层的分包情况,和物理层的建连时间是需要被考虑的。