输入url到页面渲染的过程,有你那些必知必会的HTTP面试题当我们输入url按下回车键的那一刻开始,到浏览器将页面呈现到
引言
当我们输入url按下回车键的那一刻开始,到浏览器将页面呈现到我们眼前为止,中间发生了什么过程?这是一个贯穿整个前端的问题。我们可以将之分为两个子过程:前半段是网络请求过程,后半段是浏览器渲染过程。本文重点讲述网络请求过程,解答面试中常碰到的HTTP相关的问题。
网络请求过程
假如我们要访问百度的网站,输入的URL www.baidu.com 只是一个域名,网络世界中真正能标识有效身份的是IP地址,需要解析域名得到IP地址;拿到IP地址之后就要进行网络通信了,这个时候客户端和服务端就要建立连接,进行TCP的三次握手;握手成功就开始进行大量的数据传输,数据的传输遵照HTTP超文本传输协议(但现在遵照HTTPS协议);数据传输完毕后,通过TCP四次挥手断开连接。
HTTPS 与 HTTP 的主要区别在于数据传输的安全性以及加密机制:
HTTPS 使用 TLS 协议对数据进行加密,先用非对称加密方式对密钥传输进行加密,再用对称加密方式对数据传输进行加密,确保数据在传输过程中不被第三方窃听或篡改
非对称加密:对密钥的传输进行加密 —— 服务端创建公钥发送给客户端,客户端用公钥加密私钥后传递给服务端,公钥的解密方法只有服务端自己知道,这样两边都持有密钥了并且也不会泄漏给第三方
对称加密:双方持有密钥,用密钥对数据的传输进行加密
以下针对面试中常见的问题,对网络请求过程的四个步骤依次作详细介绍:
域名解析得到IP地址 (DNS解析)
解析域名有以下几个步骤,从上至下依次执行,直到找到对应的IP地址:
- 先到本地域名服务器 (127.0.1) 查找缓存。若曾经访问过这个网站,电脑里有个DNS缓存文件会缓存起来,下一次访问就会更快
- 到根域名服务器查找缓存
- 到COM顶级域名服务器查找缓存 (顶级域名服务器还有.org、.net等对应的服务器)
- baidu.com 域名服务器查找缓存
- 本地缓存该ip地址减少下次dns的步骤
TCP建立连接
TCP是一种面向连接的、可靠的、基于字节流的传输层通信协议,它确保数据能够准确无误地从一台计算机传送到另一台计算机。简单来说,TCP就像是一个邮递员,负责确保你寄出的信件能够安全到达目的地,并且按顺序排列好。
TCP协议的标志位
TCP使用多种标志位来管理连接的建立、数据传输和关闭,标志位及标志位的组合都给数据传输附加了不同的含义:
- URG=1: 表示有紧急信息
- ACK=1:表示已成功接收的数据
- SYN=1 & ACK=0:表示请求报文 (即请求连接的数据包)
- SYN=0 & ACK=1:表示应答报文 (即应答确认的数据包)
TCP三次握手
- 客户端向服务端发送建立连接的请求,客户端进入 SYN-SENT 状态
- 服务端向客户端发送同意应答,服务端进入SYN-RECEIVED 状态
- 客户端向服务端发送确认接收到了服务端的同意应答
- TCP为什么一定要3次握手?2次行不行?
如果两次就会导致服务器资源浪费:当客户端向服务端发送建立连接请求A,但是因为网络问题导致A请求超时,TCP的超时重传机制会再次发送一个新的建立连接请求B,当B被应答后数据通讯也完成了,连接释放,双方进入close状态。
一旦此时A请求又再次出现,那么服务端认为又有客户端要跟他建立连接,从而应答并进入SYN-RECIEVED
的状态等待数据传输,但其实根本没有客户端给它发送数据,这将造成服务端资源浪费。
而TCP的3次握手机制面对上述同样的场景时,若服务端没有等到第三次握手信息,则会认为A是无效的请求,直接关闭连接,释放资源,避免资源的浪费
基于Http协议的数据传输
HTTP超文本传输协议定义了客户端与服务器之间交换数据的标准方式,从被打造出来到现在共经历了 0.9、 1.0、 1.1 和 2.0 四个版本,3.0 版本也正计划更新。
HTTP 0.9 版本
最初的 0.9 版本只需要满足少数人的需求,进行一些无任何样式的HTML文件传输,所以协议的规范要求也比较简洁:
- 基于TCP协议建立连接:即要经历DNS解析、建立连接、TCP三次握手后再进行遵循HTTP协议的数据传输
- 客户端发送请求行,格式类似 GET /index.html,只包含方法和目标资源的路径
- 服务端接收到请求后,读取HTML文件,以ASCII码字符流的形式返回给客户端
- 0.9 版本的特点
- 只有请求行,没有请求头和请求体
- 服务器也没有响应头,只有响应体,直接只返回一个HTML文件,若不存在该资源也不返回任何额外信息
- 都是用ASCII字符流传输的
HTTP 1.0 版本
核心需求:为了HTTP能够支持多种类型文件的传输,比如js, css, 图片,音频,视频等等...相比 0.9 版本做出了以下改进:
1. 引入请求头和响应头:
-
请求头:
- accept:text / html (浏览器期望接收到的文本类型)
- accept-encoding: gzip, deflate, br (浏览器支持的压缩方式)
- accept-Charset: utf-8 (浏览器支持的编码方式)
- accept-language: zh-CN, zh (浏览器支持的语言文件)
-
响应头:
- content-type: text/html; charset=utf-8 (服务器返回的文本类型)
- content-encoding: br (服务器返回的压缩方式)
2. 引入了状态码
-
1xx 信息响应
- 这些状态码表示接收请求的服务器正在处理请求的过程中。例如,
100 Continue
表示客户端可以继续发送请求的剩余部分。
- 这些状态码表示接收请求的服务器正在处理请求的过程中。例如,
-
2xx 成功
- 这些状态码表示请求已经被成功处理。最常见的状态码是
200 OK
,表示请求已成功并被处理。
- 这些状态码表示请求已经被成功处理。最常见的状态码是
-
3xx 重定向
- 这些状态码指示客户端需要采取进一步的动作来完成请求。例如,
301 Moved Permanently
表示请求的资源已被永久移动到一个新的URI,客户端应该使用新的URI。
- 这些状态码指示客户端需要采取进一步的动作来完成请求。例如,
-
4xx 客户端错误
- 这些状态码表示请求包含语法错误或无法完成请求。例如,
400 Bad Request
表示请求无法被理解,403 Forbidden
表示服务器理解请求客户端的请求,但是拒绝执行此请求。
- 这些状态码表示请求包含语法错误或无法完成请求。例如,
-
5xx 服务器错误
- 这些状态码表示服务器在处理请求时遇到错误。例如,
500 Internal Server Error
表示服务器遇到了意外的情况,无法完成请求。
- 这些状态码表示服务器在处理请求时遇到错误。例如,
3. 引入了HTTP Cache 机制
HTTP 1.1 版本
1.0 时代,http是短链接,随着浏览器的普及,传输资源的种类增多,一个html文件的传输也会伴随更多依赖资源的传输,若每传输一次都重新建立连接、重新发送请求和响应、再重新断开连接,会增大很多无谓的开销。
更新后的 1.1 :
- 增加了持久连接的方法。建立一个TCP连接,可以传输多个http请求,有效减少连接和断开次数,减少开销。若还是想用1.0的短链接,
Connection: close
可以关闭持久连接
同时也带来了一个问题——http队头阻塞:一次连接可以发多个请求,但必须等待前一个请求的响应结束才可以继续发送下一个,若前面的请求延迟,会导致后面的请求也被延迟
-
一个域名支持同时建立多个连接,减少资源传输的等待时间
-
提供了虚拟机支持:以前一个域名只能绑定一个IP地址,但一个物理主机可以绑定多个虚拟机,每个虚拟机有单独的域名 HOST:XXXX,这些单独的域名又可以共用同一个IP地址
-
Chunk transfer机制:服务端将数据分割成若干个任意大小的数据块,每个数据块上标记数据块大小,最后使用一个长度为0的空数据块作为传输完成的标志
-
引入Cookie机制,允许服务器在客户端存储小量的数据
1.1 版本还存在一个问题就是宽带利用率低下,原因:
- TCP的慢启动:TCP协议采用了一个由慢到快的传输加速度,不管网速多快,TCP连接刚建立时发送的数据包都是很少的。TCP稳定可靠安全,但不高效
- 同时开启多个TCP连接,这些连接之间相互竞争带宽,会导致那些关键资源的传输受阻
- http队头阻塞
HTTP 2.0 版本
为了改善 1.1 版本的宽带利用率低下的问题,采用了一个多路复用策略:
- 不允许同时建立多个TCP连接,一个域名只能建立一个TCP连接,解决掉连接之间相互竞争带宽的问题
- 采用二进制分帧层,将所有的请求处理为一帧一帧的请求,每一帧请求都带上独特的id编号,服务端根据id区分拼接完整请求体,并以同样的方式返回响应,以同时处理多个请求和响应并且确保更重要的请求优先得到处理
由于HTTP 2.0 版本仍然是基于TCP制定的,存在TCP队头阻塞问题:
- 慢启动
- TCP在传输过程中,一旦发生单个数据包丢失,其他后续的数据包会暂停发送,等重新将丢失的数据包再次整理好后,再次启动传输
HTTP 3.0 版本
我们现在基本上还是用的HTTP 2.0 版本,但是随着各领域产品更新换代, HTTP 3.0 版本也会在将来普及开来。 3.0 版本采用了QUIC协议,它可以被看做 TCP 和 UDP 协议精华的综合,具有以下几个优点:
- TCP的可靠性
- TLS加密
- 多路复用
- 快速握手
简单聊一下CP 和 UDP 的区别
- TCP:
- 面向有连接,即在通信之前,必须建立连接,然后才能发送数据,在通信之后,必须关闭连接,否则会占用大量资源
- 可靠性:有流量拥塞控制
- 有序性:若有包丢失,则暂停后续包的发送,重新传一份被丢失的包,再发送后续包
- UDP:
- 无连接
- 不可靠:无流量拥塞控制,丢包不管
- 高效:对于实时性很高的场景 比如 游戏、视频通话等有很高适用性
TCP 四次挥手断开连接
- 客户端向服务端发送释放连接的请求
- 服务端接收到释放连接的请求,进入CLOSE_WATT状态,向客户端发送同意断开的应答
- 服务端向客户端发送还未发送完的数据,服务端进入LAST_ACK状态
- 客户端接收到同意的应答后,向服务端发送确认接收应答,双方进入CLOSE状态
浏览器渲染过程
- 解析HTML文件,生成DOM树
- 同时下载并解析css样式表,生成 css规则树;再与DOM树合并成Render渲染树
- 同时解析js脚本,但在css样式表解析之后才会执行
- 布局渲染树中每个结点的位置和尺寸
- 根据布局在页面上绘制出每个元素
- GPU合成默认图层和复合图层,最后显示出页面
以上通过介绍输入url到页面渲染的过程来带你了解了一些面试中常碰到的HTTP相关面试题,相信你认真读完一定能在面对面试官的提问时不再无话可说~
转载自:https://juejin.cn/post/7403683232807747635