浏览器输入URL后发生了什么?

注意:本文的步骤是建立在,请求的是一个简单的 HTTP 请求,没有 HTTPS、HTTP2、最简单的 DNS、没有代理、并且服务器没有任何问题的基础上,尽管这是不切实际的。

大致流程

  1. URL 解析
  2. DNS 查询
  3. TCP 连接
  4. 处理请求
  5. 接受响应
  6. 渲染页面

一、URL解析

URL(Universal Resource Locator):统一资源定位符。俗称网页地址或者网址。

URL用来表示某个资源的地址。(通过俗称就能看出来)

URL主要由以下几个部分组成:

  • a.传输协议
  • b.服务器
  • c.域名
  • d.端口
  • e.虚拟目录
  • f.文件名
  • g.锚
  • h.参数

也就是说,通常一个URL是像下面这样

连起来就是:http://www.aspxfans.com:8080/news/index.asp?boardID=5&ID=24618&page=1#name

上面的链接有几个要注意的地方:“:” 和“/”的使用,80端口默认不显示,“?” 到“#”之间跟着参数,多个参数使用“&”连接,“#”后面跟着锚。

二、DNS解析

DNS解析(域名解析),DNS实际上是一个域名和IP对应的数据库。

IP地址往都难以记住,但机器间互相只认IP地址,于是人们发明了域名,让域名与IP地址之间一一对应,它们之间的转换工作称为域名解析,域名解析需要由专门的域名解析服务器来完成,整个过程是自动进行的。

可以在浏览器中输入IP地址浏览网站,也可以输入域名查询网站,虽然得出的内容是一样的但是调用的过程不一样,输入IP地址是直接从主机上调用内容,输入域名是通过域名解析服务器指向对应的主机的IP地址,再从主机调用网站的内容。

DNS解析基本步骤:

1.浏览器缓存

浏览器会缓存之前拿到的DNS 2-30分钟时间,浏览器会先检查是否在缓存中,没有则调用系统库函数进行查询。

2.操作系统缓存

检查hosts文件,这个文件保存了一些以前访问过的网站的域名和IP的数据。它就像是一个本地的数据库。如果找到就可以直接获取目标主机的IP地址了。

3.路由器缓存

路由器有自己的DNS缓存,可能就包括了正在查询的内容。

4.ISP DNS 缓存

ISP DNS 就是在客户端电脑上设置的首选 DNS 服务器,它们在大多数情况下都会有缓存。

根域名服务器查询

在前面所有步骤没有缓存的情况下,本地 DNS 服务器会将请求转发到互联网上的根域,下面这个图很好的诠释了整个流程:

递归查询:从根域名服务器到顶级域名服务器再到极限域名服务器依次搜索哦对应目标域名的IP。

三、TCP 连接

TCP/IP 分为四层,在发送数据时,每层都要对数据进行封装:

1. 应用层:发送 HTTP 请求

在前面的步骤我们已经得到服务器的 IP 地址,浏览器会开始构造一个 HTTP 报文,其中包括:

  • 请求报头(Request Header):请求方法、目标地址、遵循的协议等等
  • 请求主体(其他参数)

其中需要注意的点:浏览器只能发送 GET、POST 方法,而打开网页使用的是 GET 方法

2. 传输层:TCP 传输报文

传输层会发起一条到达服务器的 TCP 连接,为了方便传输,会对数据进行分割(以报文段为单位),并标记编号,方便服务器接受时能够准确地还原报文信息。

在建立连接前,会先进行 TCP 三次握手。

3. 网络层:IP协议查询Mac地址

将数据段打包,并加入源及目标的IP地址,并且负责寻找传输路线。

判断目标地址是否与当前地址处于同一网络中,是的话直接根据 Mac 地址发送,否则使用路由表查找下一跳地址,以及使用 ARP 协议查询它的 Mac 地址。

注意:在 OSI 参考模型中 ARP 协议位于链路层,但在 TCP/IP 中,它位于网络层。

4. 链路层:以太网协议

以太网协议

根据以太网协议将数据分为以“帧”为单位的数据包,每一帧分为两个部分:

  • 标头:数据包的发送者、接受者、数据类型
  • 数据:数据包具体内容

Mac 地址

以太网规定了连入网络的所有设备都必须具备“网卡”接口,数据包都是从一块网卡传递到另一块网卡,网卡的地址就是 Mac 地址。每一个 Mac 地址都是独一无二的,具备了一对一的能力。

广播

发送数据的方法很原始,直接把数据通过 ARP 协议,向本网络的所有机器发送,接收方根据标头信息与自身 Mac 地址比较,一致就接受,否则丢弃。

注意:接收方回应是单播

四、服务器处理请求

大致流程

HTTPD

最常见的 HTTPD 有 Linux 上常用的 Apache 和 Nginx,以及 Windows 上的 IIS。它会监听得到的请求,然后开启一个子进程去处理这个请求。

处理请求

接受 TCP 报文后,会对连接进行处理,对HTTP协议进行解析(请求方法、域名、路径等),并且进行一些验证:

  • 验证是否配置虚拟主机
  • 验证虚拟主机是否接受此方法
  • 验证该用户可以使用该方法(根据 IP 地址、身份信息等)

重定向

假如服务器配置了 HTTP 重定向,就会返回一个 301永久重定向响应,浏览器就会根据响应,重新发送 HTTP 请求(重新执行上面的过程)。

URL 重写

然后会查看 URL 重写规则,如果请求的文件是真实存在的,比如图片、html、css、js文件等,则会直接把这个文件返回。

否则服务器会按照规则把请求重写到 一个 REST 风格的 URL 上。然后根据动态语言的脚本,来决定调用什么类型的动态文件解释器来处理这个请求。

以 PHP 语言的 MVC 框架举例,它首先会初始化一些环境的参数,根据 URL 由上到下地去匹配路由,然后让路由所定义的方法去处理请求。

五、浏览器接受响应

浏览器接收到来自服务器的响应资源后,会对资源进行分析。

首先查看 Response header,根据不同状态码做不同的事(比如上面提到的重定向)。如果响应资源进行了压缩(比如 gzip),还需要进行解压。

然后,对响应资源做缓存。接下来,根据响应资源里的 MIME 类型去解析响应内容(比如 HTML、Image各有不同的解析方式)。

六、浏览器渲染页面

客户端拿到服务器端传输来的文件,找到HTML和MIME文件,通过MIME文件,浏览器知道要用页面渲染引擎来处理HTML文件。

a.浏览器会解析html源码,然后创建一个 DOM树。

在DOM树中,每一个HTML标签都有一个对应的节点,并且每一个文本也都会有一个对应的文本节点。

b.浏览器解析CSS代码,计算出最终的样式数据,形成css对象模型CSSOM。

首先会忽略非法的CSS代码,之后按照浏览器默认设置——用户设置——外链样式——内联样式——HTML中的style样式顺序进行渲染。

c.利用DOM和CSSOM构建一个渲染树(rendering tree)。

渲染树和DOM树有点像,但是是有区别的。

DOM树完全和html标签一一对应,但是渲染树会忽略掉不需要渲染的元素,比如head、display:none的元素等。

而且一大段文本中的每一个行在渲染树中都是独立的一个节点。
渲染树中的每一个节点都存储有对应的css属性。

d.浏览器就根据渲染树直接把页面绘制到屏幕上。

基本流程图

------ 本文结束感谢您的阅读 ------
坚持原创技术分享,您的支持将鼓励我继续创作!