乐趣区

输入URL到页面加载中间发生了什么

背景


刚开始要写这篇文章的时候,其实我是拒绝的。这类文章随便一搜就一大把,但是想了一下之后,还是决定写出来。一方面是想再仔细梳理一下这个过程和其中的一些细节,另一方面也想用简洁的语言来加深对这个问题的认知。中间也参考了很多大佬的文章,也算是一次复习回顾,顺便总结在这里,方便查阅。

大致的过程

  1. 浏览器根据输入的域名,通过 DNS 查询 IP.
  2. 浏览器根据 IP 与服务器 建立 Socket 连接.
  3. 浏览器与服务器 通信: 浏览器发送请求,服务器处理请求,浏览器处理服务器返回的数据.
  4. 浏览器与服务器 断开连接.

每一步都发生了什么

1. 根据域名查询 IP

一些基础概念:

IP 地址:IP 协议为互联网上的每一个网络和每一台主机分配的一个逻辑地址。IP 地址如同门牌号码,通过 IP 地址才能确定一台主机位置。服务器本质也是一台主机,想要访问某个服务器,必须先知道它的 IP 地址;

域名(Domain Name):IP 地址由四个数字组成,中间用点号连接,在使用过程中难记忆且易输入错误,所以用我们熟悉的字母和数字组合来代替纯数字的 IP 地址,比如我们只会记住 www.baidu.com(百度域名)而不是 220.181.112.244(百度的其中一个 IP 地址);

DNS (Domain Name System):每个域名都对应一个或多个提供相同服务服务器的 IP 地址,只有知道服务器 IP 地址才能建立连接,所以需要通过 DNS 把域名解析成一个 IP 地址。

查找 IP 的过程

  1. 浏览器搜索自己的 DNS 缓存((浏览器维护一张域名与 IP 地址的对应表);如果没有命中,进入下一步;)
  2. 搜索操作系统中的 DNS 缓存(维护一张域名与 IP 地址的对应表, 如果没有命中,进入下一步;);
  3. 搜索操作系统的 hosts 文件(Windows 环境下,维护一张域名与 IP 地址的对应表,如果没有命中,进入下一步);
  4. 操作系统将域名发送至 LDNS(本地区域名服务器,如果你在学校接入互联网,则 LDNS 服务器就在学校,如果通过电信接入互联网,则 LDNS 服务器就在你当地的电信那里。)LDNS 查询自己的 DNS 缓存(一般查找成功率在 80% 左右),查找成功则返回结果,失败则发起一个迭代 DNS 解析请求:

    1. LDNS 向 Root Name Server(根域名服务器,其虽然没有每个域名的的具体信息,但存储了负责每个域,如 com、net、org 等的解析的顶级域名服务器的地址)发起请求,此处,Root Name Server 返回 com 域的顶级域名服务器的地址;
    2. LDNS 向 com 域的顶级域名服务器发起请求,返回 baidu.com 域名服务器地址;
    3. LDNS 向 baidu.com 域名服务器发起请求,得到 www.baidu.com 的 IP 地址;
  5. LDNS 将得到的 IP 地址返回给操作系统,同时自己也将 IP 地址缓存起来;
  6. 操作系统将 IP 地址返回给浏览器,同时自己也将 IP 地址缓存起来;
  7. 至此,浏览器已经得到了域名对应的 IP 地址。

建立连接

知道了服务器的 IP 地址,下面便开始与服务器建立连接了。

通俗地讲,通信连接的建立需要经历以下三个过程:

  1. 主机向服务器发送一个建立连接的请求(您好,我想认识您);
  2. 服务器接到请求后发送同意连接的信号(好的,很高兴认识您);
  3. 主机接到同意连接的信号后,再次向服务器发送了确认信号(我也很高兴认识您),自此,主机与服务器两者建立了连接。

TCP 协议:三次握手的过程采用 TCP 协议,其可以保证信息传输的可靠性,三次握手过程中,若一方收不到确认信号,协议会要求重新发送信号。

网页请求与显示

当服务器与主机建立了连接之后,下面主机便与服务器进行通信。网页请求是一个单向请求的过程,即是一个主机向服务器请求数据,服务器返回相应的数据的过程。

浏览器根据 URL 内容生成 HTTP 请求,请求中包含请求文件的位置、请求文件的方式等等;

服务器接到请求后,会根据 HTTP 请求中的内容来决定如何获取相应的 HTML 文件;

服务器将得到的 HTML 文件发送给浏览器;

在浏览器还没有完全接收 HTML 文件时便开始渲染、显示网页;

在执行 HTML 中代码时,根据需要,浏览器会继续请求图片、CSS、JavsScript 等文件,过程同请求 HTML;

断开连接 – 四次挥手

  1. 主机向服务器发送一个断开连接的请求(不早了,我该走了);
  2. 服务器接到请求后发送确认收到请求的信号(知道了);
  3. 服务器向主机发送断开通知(我也该走了);
  4. 主机接到断开通知后断开连接并反馈一个确认信号(嗯,好的),服务器收到确认信号后断开连接;

补充说明

为什么服务器在接到断开请求时不立即同意断开:
当服务器收到断开连接的请求时,可能仍然有数据未发送完毕,所以服务器先发送确认信号,等所有数据发送完毕后再同意断开。

第四次握手后,主机发送确认信号后并没有立即断开连接,而是等待了 2 个报文传送周期
原因是:如果第四次握手的确认信息丢失,服务器将会重新发送第三次握手的断开连接的信号,而服务器发觉丢包与重新发送的断开连接到达主机的时间正好为 2 个报文传输周期。

写到这里,其实大概也差不多了。但事实上还有很多复杂的细节,同时也不缺乏好玩的过程。

比如为什么你输入 www.google.cn 并按了 enter 之后会跳出来一个“无法访问此网站”,再比如当浏览器得到了从服务器传过来的 html,css 等文件后是怎么将页面呈现出来的。

这些以后我将一一跟大家叙述,欢迎关注~

参考文章:
https://juejin.im/entry/59c3a…
https://mp.weixin.qq.com/s/zm…

退出移动版