从输入URL到看到页面,究竟发生了什么?这个问题需要分为两个部分来回答。1:HTTP请求 2:浏览器渲染
1、首先是HTTP请求:
发起HTTP请求之前,先确认请求内容是否有本地缓存。
提到HTTP,与之密不可分的就是TCP/IP协议族。TCP/IP分为四个层级:应用层(HTTP)--传输层(TCP)--网络层(IP)--链路层。
1.1 HTTP、DNS、SSL
如果输入的URL是一个域名,则需要通过DNS协议解析成IP地址。
HTTP协议生成针对目标地址的请求报文。
请求报文包括的主要字段有:请求类型(比如get post 前者主要用于获得请求主体内容 后者主要用于传输主体内容 其他的比如PUT/DELETE 上传/删除文件 HEAD只返回相 应头) uri http版本 请求首(头) 正文(主体)
管线化链接:http1.1提出的持久链接(connection:keep-alive)
SSL:对于HTTPS的请求,会先通过SSL协议(公钥私钥方法以及混合加密)建立加密的通信管道,之后再进行正常的http请求,此外SSL可校验服务器证书,可校验内容的完整性。
HTTPS=HTTP+加密通信+证书验证+内容完整校验
1.2 TCP
TCP将HTTP协议生成的请求报文进行分割,标记序列号以及端口号后转发给网络层
TCP协议会通过三次握手策略,确保双方的通信正常。发送方发送一个SYN(可以理解为请求同步标志)给对方。接收方接收后返回SYN(请求同步) & ACK(确认同步),请求 方收到接收方新的SYN后再次回复ACK以及数据包,三次握手结束
此过程一旦终端,会重新开始
1.3 IP(internet protocol)
接受TCP过来的数据,并添加通信目标地址后交给链路层
能够传达目的地,需要IP协议明确对方IP地址和MAC地址(MAC地址可以是对方的主机MAC地址也可以是中间中转点的MAC地址,如果是经过MAC中转,MAC搜索下一个MAC的过程将会使用ARP协议解析地址)。
1.4链路层
就是物理传输层,比如网路,路由等
1.5 接受端--链路层--IP层--TCP层--HTTP层
与发出的顺序相反,来解析接收的请求,并给出响应。
如果接收方是代理服务器,则首先判断有没有代理缓存,没有会请求最终服务器。有就直接返回(最终服务器可以通过cache-control控制缓存与否)
出于安全,引入了cookie,可以根据cookie判断会话状态(服务端会校验请求带来的cookie的有效期、域、协议等信息)。
1.6 响应状态
响应可以为0:比如跨域的情况
2XX:请求是没问题的,也正常返回。但返回结果视情况而定
3XX:服务器需要经过处理才能正常返回,如果资源已经更新而请求的还是老内容,或者不符合请求头中的条件
4XX:服务端无法理解等因为客户端原因导致的失败
5XX:服务端出错导致失败
2、浏览器渲染
当成功从服务器返回内容后,就会进行渲染。
2.1 DOM树 样式 渲染树 渲染
浏览器解析HTML成DOM树。树的每个节点对应一个HTML元素。
解析样式,会对应到DOM树中的每个节点。
渲染树类似于添加了样式的DOM树,但是渲染树不含隐藏的元素
完成渲染树后,渲染页面。
2.2 渲染阻塞
按序加载可以导致阻塞,此处不详述。
JS通常因为单线程原因导致渲染阻塞。但其实js单线程而浏览器不是单线程。浏览器除了有JS线程还有渲染线程此外还有定时器线程等。
渲染线程和JS线程虽然独立,但是JS依然能够阻塞渲染线程。这主要是因为:如果渲染线程准备给DOM1渲染为红色,在渲染过程中,如果JS线程可以同步执行,而又JS又在操作DOM1的颜色为蓝色,此时就会发生一些矛盾。为了避免这样的事情发生,所以JS线程在执行的时候,渲染线程会被临时挂起。这也导致了,JS可能引起渲染阻塞。