从浏览器上键入一个URL到页面展示的过程中发生了什么

从浏览器上键入一个URL到页面展示的过程中发生了什么


前言

如果要非常全面的回答好这个问题,个人觉得还是稍微有点难的。例如,根据请求资源类型,如果是静态资源可能会去到CDN服务,如果是动态资源,可能需要经过好几层的网关/代理、然后是WEB服务器、接着是缓存、数据库等层面的操作。

进一步细讲,还能说到浏览器建立连接的过程,其中HTTP和HTTPS又有些差别。另外还有,请求经过传输层、网际层封装形成的报文,以及在链路层通过网卡设备将数据包发送出去的细节。

如果挖根刨底的讲,还能扯到不同的运营商(移动、电信、联通)对数据包的编码、解码方式以及不同运营商之间如何进行数据交互的过程。

因此,考虑一个较为简单的模型,该模型中,主要角色如下,不考虑任何缓存、代理等优化机制:

  1. 一个浏览器
  2. 一台服务器
  3. 发起HTTP请求

那么过程如下(不考虑浏览器直接输入IP地址的情况):


DNS 解析

DNS,域名系统(服务)协议(DNS),DNS的解析过程,其实就是寻找域名所对应的IP地址的过程。那从哪里寻找呢?

  1. 首先是浏览器缓存,浏览器一般会对解析过的域名对应的IP进行缓存,这个缓存时间会和TTL(Time-To-Live,域名解析记录的存留时间)的设置有关。
  2. 如果浏览器缓存中没有命中,浏览器会检查操作系统缓存中有没有对应的解析记录。
关于第二点,在windows系统中,我们可以通过hosts文件进行设置。
  1. 如果依然不能命中,此时会请求本地域名服务器(LDNS)来解析这个域名。
关于LDNS一般是指你电脑上网时IPv4或者IPv6设置中填写的DNS,这个可以是手工指定的,也可以是DHCP自动分配的。很多小伙伴在查询的时候,会发现地址是一个内网地址,其实也很正常。现在很多都使用的是WiFi连接,我们看到的地址其实是路由器的地址,而路由器里头有DNS转发器,它会将请求转发到上层ISP的DNS。例如,我用nslookup命令查询,结果如下:

在这里插入图片描述

  1. 如果LDNS仍然没有命中,就来到根域名服务器请求解析。
根域名服务器返回给LDNS一个所查询域的主域名服务器(gTLD Server,国际顶尖域名服务器,如.com .cn .org等)地址, 这个地址也是权威服务器的地址。
关于权威服务器,它是特殊的DNS服务器,而所谓的权威是针对特定域名来说的。它是域名商在管理,解析在他这里购买的域名的权威解析
  1. 本地服务器再向第四步返回的域名服务器发送请求,接受请求的服务器查询自己的缓存,如果没有该纪录,则返回相关的下级的域名服务器的地址(递归查询)。

  2. 重复第5步,直到找到正确的纪录。

  3. 本地域名服务器(LDNS)缓存这个域名和对应的ip,以备下次使用。

  4. 最后,LDNS将解析的结果返回给用户,用户根据TTL值缓存到本地系统中


HTTP请求

在该过程中,包括了建立连接、发送 HTTP 请求、返回 HTTP 响应、维持连接和释放连接5个过程。

  1. 建立链接,考虑TCP连接的情况,该过程包含了三次握手。对应服务器的端口状态变化情况为:listen、syn_rcvd和established。如果请求为HTTPS的情况,那交互细节又复杂了一些,关于HTTPS的展开,计划再谋划出一篇文章来。

  2. 发送 HTTP 请求,一个请求报文由请求行、请求头、空行、实体(Get 请求没有)组成。在传输层进一步封装成TCP传输报文。然后,在网际层中,通过相应的ip协议查询MAC地址(ARP,地址解析协议),进一步封装成IP报文。接着,数据到达了网卡设备(对应数据链路层和物理层),网卡芯片再次封装成物理帧,并添加头部同步信息和CRC校验。然后根据情况丢到网线上,就完成一个IP报文的发送。

  3. 返回 HTTP 响应,在发送数据到服务器后,经过处理,会返回一个响应报文。根据需要,服务器会写入cookie、token等信息。此外,浏览器和服务器各自维护的队列中请求/响应顺序必须一一对应,否则会出现乱序的情况。

  4. 维持连接,HTTP/1.1 中,Connection: keep-alive 是默认启用的,表示持久连接,即连接完毕后不会马上释放,会维持一段时间。一般来说,浏览器每隔 45 秒会向服务器发送 TCP keep-alive 探测包,判断 TCP 连接是否正常,如果没有收到 ACK 应答,则主动断开与服务器的连接。对于服务器来说,这个时间可以是我们程序上进行控制,也可能是某些反向代理软件中的设置,如Nginx 中,持久连接超时的时间默认值为 75 秒,如果 75 秒内没有新到达的请求,则断开与客户端的连接。

  5. 释放连接,同样考虑TCP连接,在释放连接的过程也就是我们常说的四次分手,具体已在这边文章进行描述


浏览器解析

图片摘自此链接,详细细节可以参考此文档
在这里插入图片描述
关于浏览器的渲染,不同的浏览器可能具有着不同的实现方式,但主要涉及如下几个模块的内容:

  1. user interface :浏览器交互界面
  2. browser engine:浏览器引擎:接收用户界面指令传给解析引擎
  3. render engine:渲染引擎:负责显示请求的内容。如果请求的内容是 HTML,它就负责解析 HTML和 CSS 内容,并将解析后的内容显示在屏幕上
  4. networking:网络,用来完成网络调用,例如http请求,它具有平台无关的接口,可以在不同平台上工作
  5. javascript 解释器,解释执行JS代码
  6. ui backend:用于绘制基本的窗口小部件
  7. database :数据存储引擎

在浏览器拿到HTML文本数据后, render engine渲染引擎开始解析html,首先将标签转化一个个dom节点,并构建起一颗内容树。

接着,解析CSS文件、style标签中的样式信息。这些样式信息以及html中的可见性指令将被用来构建成render树。

Render树又是由一些包含有颜色和大小等属性的矩形组成,它们将被按照正确的顺序显示到屏幕上。在Render树构建完后,会执行布局过程,它将确定每个节点在屏幕上的确切坐标。再下一步就是绘制,即遍历render树,并通过ui backend层绘制每个节点。

上述只是概括性的描绘了部分流程,其实关于如何构建一颗内容树并不是一个简单的步骤,需要进行文本的分析、词法的解析,然后是解析的算法、树的构建算法等方面的知识。在How browsers work一文中,为我们详细的阐述了几种主流浏览器的来龙去脉。

猜你喜欢

转载自blog.csdn.net/legendaryhaha/article/details/107217739