程序员阿沛
发布于 2026-06-27 / 0 阅读
0
0

浏览器输入一个网址发生了什么一揭秘DNS请求和解析全流程

浏览器输入一个网址发生了什么(一) 揭秘DNS请求和解析全流程

本系列文章归于: 计算机网络基础

从本系列文章开始将围绕着“往浏览器输入网址后发生了什么”介绍计算机网络的相关基础知识。
本文将介绍往浏览器中输入一个网址后客户端如何封装http消息和发送dns请求查询目标主机的ip的过程。
以下是本文的知识点概览:

  1. URL解析 :
* 含义  :URL解析是浏览器对输入的网址进行解析的过程,包括协议、域名、端口、路径等信息的提取。

* 目的  :为后续的HTTP请求和DNS查询提供必要的参数。
  1. HTTP请求消息封装 :
* 过程  :在URL解析完成后,客户端会根据请求的类型(如GET、POST)生成HTTP请求消息。

* 内容  :HTTP请求消息包括请求行、请求头、请求体等部分,用于向服务器传达请求信息。
  1. DNS查询过程 :
* 流程  :客户端在发送HTTP请求前,需要先通过DNS查询获取目标主机的IP地址。这个过程包括递归查询和迭代查询两种方式。

* 涉及实体  :DNS查询涉及本地域名服务器、根域名服务器、顶级域名服务器和权威域名服务器等多个实体。
  1. IP地址与子网划分 :
* IP地址结构  :IP地址分为网络号和主机号两部分,用于标识主机在网络中的位置。

* 子网划分  :子网划分是通过在网络号中借用若干位作为子网号来实现的,用于提高网络的灵活性和效率。
  1. 浏览器与操作系统协作 :
* 缓存机制  :浏览器和操作系统都有DNS缓存机制,用于存储域名与IP地址的映射关系,减少DNS查询次数。

* 用户态与内核态切换  :在DNS查询过程中,用户程序(浏览器)会切换到操作系统的内核态运行DNS解析器。
  1. DNS解析器的工作原理 :
* 功能  :DNS解析器是操作系统socket库中的一段程序,用于向DNS服务器发送查询请求并获取域名对应的IP地址。

* 实现方式  :DNS解析器通过调用系统调用函数(如gethostbyname())来实现DNS查询功能。
  1. 域名解析的层次结构 :
* 顶级域名服务器  :负责处理对顶级域名的查询请求。

* 权威域名服务器  :负责处理对特定域名的查询请求,并返回对应的IP地址。

* 根域名服务器  :负责处理对所有域名的根查询请求,并返回顶级域名服务器的IP地址。
  1. HTTP请求的发送与接收 :
* 发送过程  :客户端将封装好的HTTP请求消息通过TCP/IP协议栈发送到服务器。

* 接收过程  :服务器接收到HTTP请求后,进行处理并返回HTTP响应消息给客户端。

正文开始: 往浏览器输入网址后发生了什么?

1. 客户端(如浏览器)解析 url

url 的组成部分如下所示:

客户端会按照 协议、域名、文件路径以及请求参数 对 url 进行解析(就是解析出以上信息)。

url 如果没有以 / 结尾表示访问一个指定文件,以 / 结尾表示访问指定目录下的默认文件,例如:

http://www.lab.glasscom.com/dir/ 访问的是 /dir 目录下的 index.html 文件。

http://www.lab.glasscom.com/dir 访问的是 /dir 文件。但是如果不存在 /dir
文件,则会把它当做是目录处理,因而会访问 /dir/ 下的默认文件

2. 生成 http 请求消息

解析完 url 后,客户端会根据请求的类型(这里以 GET 和 POST 为例)生成 http 请求消息。 http
请求消息和响应消息如下所示:

PS : get 请求没有消息体, post 才有。

消息头就是我们所说的 header 字段,包含诸如 Content-Type 、 Cookie 、 Host 等内容。

请求行的 URI 包括文件路径和请求参数。

请求消息和响应消息的不同仅在第一行

一个请求消息中只能写一个 URI 。

如下为 get 和 post 请求报文格式:

客户端会根据上述 (a) 的格式生成 http 消息。

** * 头信息列举: **

通用头

请求头

响应头

响应消息中的状态码概述

3. 向 DNS 服务器查询域名对应 IP

客户端生成 http 消息后会委托操作系统将消息发送给 web 服务器。操作系统拿到 http
报文后为了将其发送给web服务器,会先根据域名查询目标主机的 IP 地址。

** * 简单了解 IP 相关知识 **

在网络中,所有设备都会被分配一个 IP 地址, IP 地址相当于是服务器的坐标,客户端得知这个坐标才能将消息发送到服务器主机。

实际的 IP 是一串 32 比特的数字( IPv4 标准),并按 8 比特分为 4 组,每组用原点隔开,每组以十进制表示。除了
IPv4 标准外还有 IPv6 标准, IPv6 下的 IP 地址则是 128 比特的长度用于支持更多可能的地址,这里只介绍 IPv4
下的内容。

IP 地址分为网络号和主机号两部分,网络号代表主机所在的子网网络,子网与子网间通过路由器和集线器连接和通信,主机号代表某台主机在子网中的具体位置。

IP 地址被分为 A~E 类,每类的网络号和主机号长度是不定的,例如 C 类 IP 的前 3 个字节是网络号,第 4
个字节是主机号;而 B 类 IP 地址前 2 个字节是网络号,后两个字节是主机号。

IP 地址会用附加信息来表示哪部分是 IP 的网络号,哪部分是 IP 的主机号。这个附加信息就是子网掩码。子网掩码是一串与 IP 长度相同的
32 比特数字,也分为主机号和网络号,其中左边一半全为 1 ,右边一半全为 0 ,全为 1 的部分为网络号,全为 0 的部分为主机号。

例如: 10.11.12.13/255.255.255.0 中 255.255.255.0 就是子网掩码,它的前 3 字节是 1
,第四字节为 0 ,因此表示 10.11.12.13 中前 3 字节是网络号,第 4 字节是主机号。

此外还可以用 网络号比特数 表示子网掩码,如 24 。 24 表示前三字节为网络号 (83) , 16 表示前两个字节为网络号
(8
2) , 8 表示只有第一个字节是网络号。

域名也代表某一服务器的地址,但域名的使用是为了方便人类的记忆,而 IP 才是服务器所在主机的真正位置。

回到正题。

从域名解析为 IP 就涉及到 DNS (域名解析)

为了得到域名对应的 IP ,客户端(浏览器)在将 http 请求委托给操作系统发送前会查询浏览器的 DNS 缓存找域名对应 IP
,如果命中缓存则客户端会将 IP 带给操作系统,没有命中则操作系统会查找本机的 DNS 缓存,如果还是没有命中,操作系统就会通过 ** **
DNS 解析器 ** ** 向 DNS 服务器发起 DNS 请求。

** * 关于 DNS 解析器 **

DNS 解析器本质上是操作系统 socket 库中的一段程序,用于向 dns 服务器发送查询请求并获取域名对应的 IP 并返回给客户端。而
socket 库是用于调用网络功能的通用程序组件。

客户端通过 DNS 解析器发起 dns 请求的过程如下所示

客户端(浏览器)委托操作系统调用 socket 库的 gethostbyname()
这个系统调用函数,此时用户程序(浏览器)的工作会暂停并切换到操作系统的 dns 解析器运行,即用户态切换到内核态。

DNS 解析器根据浏览器提供的域名生成 DNS 查询消息( DNS 查询报文)并交给操作系统中的 TCP/IP 协议栈,由协议栈通过网卡以
UDP 传输的方式发送给 DNS 服务器。在这里,操作系统必须得知道 DNS 服务器的 IP ,这样操作系统才该把报文发送给那个 DNS
服务器,而这个 DNS 服务器的 IP 是已经事先设置好的,如下所示

而这个设置好的 DNS 服务器一般是距离客户端主机所在城市内不远处的一个 DNS 服务器,我们称之为本地 DNS 服务器。

发送 DNS 查询报文后, DNS 服务器会返回对应域名的 IP 地址给协议栈(至于 DNS 服务器根据域名返回对应 ip
的过程会在之后介绍),并按原路返回给 DNS 解析器,解析器将 IP
写入到浏览器指定的内存地址中(从内核态切回用户态),这样当该浏览器待会再想知道这个域名的 IP 时就直接从用户程序内存中取即可,无需在做 DNS
查询。此外,操作系统和浏览器还会对这个域名与 IP 的映射关系做缓存,即使关闭了浏览器下次再打开并请求也无需做 DNS 查询请求。除非缓存时间过期。

得到 IP 的值的浏览器终于可以开始发送 HTTP 请求消息。

4. DNS 报文在多个 DNS 服务器间的传递

当客户主机的操作系统将 DNS 查询报文发送给本地 DNS 服务器到 DNS 服务器返回 IP
给客户端主机这段期间发生了什么?这里需要介绍一下 DNS 查询报文的内容和 DNS 服务器。

** * DNS 查询报文和回答报文 **

DNS 查询和回答报文的格式是一致的,如下所示:

报文头部的12个字节包含了一些控制信息如,报文是查询还是回答报文,回答报文中告诉客户端它访问的是否为权威DNS服务器,客户端是否希望DNS服务器提供递归查询,以及该DNS服务器是否支持递归查询,回答的RR数等。

查询报文的实体部分需要包括2个部分: 要查询的域名 和 记录类型

记录类型表示域名对应何种类型的记录(即告诉 DNS 服务器,根据传过来的域名,它应该返回什么类型的响应内容)。

dns 服务器中保存着多条 ** 资源记录(RR) ** ,资源记录不只包括域名与 IP
的映射,但包括域名与其他信息的映射,而资源记录中保存的到底是域名与什么信息的映射取决于 ** 记录类型 ** 。

如类型是 A 表示该条记录是域名对应的 IP 地址;

类型为 MX ,是该域名对应的邮箱服务器域名;

类型为 CNAME ,该记录是一个别名域名对应的真正域名;

类型为 NS 时该记录存着要查询的域名是由哪个 DNS 服务器解析的(也就是记录着一个目标 DNS 服务器的域名),此时这个 DNS
服务器应该还保存着目标 DNS 服务器的域名与 IP 的映射。

如下所示:

baidu.com IN NS ns1.domain.com

baidu.com IN NS ns2.domain.com

ns1.domain.com IN A 111.222.111.111

ns2.domain.com IN A 123.111.222.111

除了上述类型,还有其他的记录类型。感兴趣的朋友可以自行查阅。

回答报文会包含多条资源记录(RR),每条资源记录包括4个字段:(Name, Value, Type,
TTL)。分别是域名,域名对应的值(如IP、权威DNS域名、邮箱域名等),记录类型,记录的有效时间。

** * 域名层级 **

一个域名的层级从左到右依次提升,每个层级用 . 分开。以 www.abc.com 为例, com 是顶级域名, com 域的下一层是
abc 域,再下一层是 www 这个名字。

** * DNS 服务器 **

DNS 服务器本质是一个 ** 存储着域名与相应信息映射关系 具有层级的、分布式数据库集群 ** 。

** 存储着域名与相应信息映射关系

DNS 服务器里面保存的数据我们称之为资源记录,如下所示:

当带有 域名、 class 和记录类型 的请求报文到达 DNS 服务器后,它会根据这 3 个信息从资源记录中找到这 3
个字段都匹配的记录返回给客户端。相当于 select 响应数据 from 表 where 域名 =“xxx” and
class=“xxx” and 记录类型 =“xxx”;

** ** 具有层级的、分布式数据库集群 **


** 分布式: ** 无论从服务器负载、数据备份和故障时高可用的角度来说,所有的域名信息不可能保存到一台 DNS
服务器上,而是由多台分布到世界上多台 DNS 服务器共同维护。

** 具有层级: ** DNS 服务器是具有层级的,其层级是根据域名的层级来划分,由上到下分为 根域名 DNS 服务器、顶级域名 DNS
服务器和权威 DNS 服务器。

全世界的根域 DNS 服务器大概有十几台。

每一台根域名服务器都知道所有顶级域名DNS服务器的域名和IP,而且不管哪一个本地域名服务器要对某个域名进行解析而自己无法解析都会首先求助于根域名服务器。

每一层 DNS 服务器都保存着下一层 DNS 服务器的所有 IP 地址,并且所有层级的每一台 DNS 服务器会保存所有根域的 DNS
服务器 IP 。这么一来就能做到在本地 DNS 服务器能找到根域 DNS 服务器IP,再从根据服务器逐层往下找到其他 DNS 服务器。

当某一台权威DNS服务器不能给出最后的查询回答,就会告诉请求者下一步应该找到哪个权威DNS服务器。

用户主机向本地域名服务器的查询都是采用递归查询(所以用户主机只用发出一次DNS请求即可得到想要的IP地址,其他的请求交给本地DNS服务器和其他DNS服务器即可),本地域名服务器向根域名服务器的查询通常采用迭代查询,但也可以采用递归查询。

如下图所示:

有了上面的扩展知识后,我们再来说 DNS 报文发送到本地 DNS 服务器后发生了什么:

www.lab.glasscom.com 为例

· DNS 查询报文到达本地 DNS 服务器后,如果本地 DNS 服务器没有记录目标域名对应的 IP ,则会将查询转发给根 DNS
服务器;

· 根域 DNS 服务器也没有该域名的资源记录,但判断出其顶级域为 com ,所以会把 com 域的 DNS 服务器的 IP 返回给本地
DNS 服务器;

· 本地 DNS 服务器再根据这个 IP 向 com 域的 DNS 服务器发起查询请求,但 com 域的 DNS 服务器也没有
www.lab.glasscom.com 的资源记录,但判断出该域名的权威域名为 glasscom.com ,找到了 glasscom.com
域的 DNS 服务器的 IP 地址并返回。

· 本地 DNS 服务器向 glasscom.com 域的 DNS 服务器发起 DNS 查询请求,查到了
www.lab.glasscom.com 的 IP

· 最终本地 DNS 服务器将目标 IP 返回给客户端主机,同时本地 DSN 服务器也会对该域名的 IP
映射进行缓存。下一次被访问到相同的域名时直接查询 DNS 缓存而不再向根域 DNS 服务器发起请求

上面这种 DNS 查询方式是迭代查询,每次都是由本地 DNS 服务器发起请求;

此外还有其他查询方式如递归查询,以及直接查询 DNS 缓存。

下面我们看看递归查询和迭代查询的区别:

递归查询

由本机查询本地 DNS 服务器,本地 DNS 服务器如果没有命中目标域名则向根服务器请求,根服务器根据顶级域名找到对应的顶级域名服务器的 IP
并向该顶级域名服务器发送请求,同理顶级域名服务器再向对应的权威域名服务器发送 DNS 查询请求的到目标地址 IP ,并将其原路返回给本机。

如下图展示了递归查询过程:

迭代查询

迭代查询就是上文中提到过的查询方式,本机请求本地域名服务器,本地域名服务器请求根域名服务器拿到顶级域名服务器的 ip
,本地域名服务器再去请求顶级域名服务器拿到权威域名服务器的 ip ,本地域名服务器再去请求权威域名服务器拿到目标 ip ,再返回给本机。

如下图

下节预告:浏览器输入一个网址发生了什么(二) TCP模块封装和传输机制


欢迎在评论区留言表达看法 或 提出你想学习的技术内容 与 面试问题,阿沛会一一作出回复。

如果本文对大家有帮助,麻烦大家动动小手点个免费的“赞”或“在看”,大家的鼓励就是阿沛持续更新的动力~

-- 往期精彩 –

计算机网络基础(八) 应用层之HTTP协议1.0、1.1、2.0和HTTP3版本性能演进

计算机网络基础(九)网络安全之对称密钥、非对称密钥、报文鉴别 和 TLS运输层安全协议

华为一面:说说看MySQL的索引类型及其作用?什么是聚簇索引和非聚簇索引?索引失效的情况有哪些?说说看回表、覆盖索引和索引下推?

华为二面:什么是零拷贝技术?mmap和sendfile如何实现零拷贝,它们是否真正实现了零拷贝?

图论 (上) 一文搞懂图的基本概念、图的存储、DFS、BFS与算法性能分析


评论