前言: 转眼已经工作两年有余,最近也是补习了一下计算机网络基础这方面的知识。于是打算开一个新坑,尽可能详细地把前端八股文之一的-----在浏览器搜索栏输入一个 url 地址之后发生了什么? 这件事说清楚。一方面把零碎的知识点整合到一起,另一方面是算是总结自己最近学习到的网络相关知识。
️由于本篇内容不是介绍你的计算机是如何接入互联网的,所以忽略一切 NAT 等其它相关知识。
那么让我们开始吧,本篇作为开篇,首先介绍 DNS(Domain Name System)域名解析系统。
附:购买凭证,我购买了一个 fffang.lol
的域名。
一. 我们在浏览器搜索栏输入了什么?
-
假设我们现在想访问百度首页,
www.baidu.com
这段文字像是被刻在了 DNA 里了一样,我们几乎是条件反射的打出了这段字符。也正因为像人的本能一样,在此之前我从没考虑过www.baidu.com
这段文字到底是什么?就好像一切就本该这样似的。不行,我得研究研究。
-
要想接着聊下去,我们首先得知道什么是ip(internet protocol)。想必你或多或少听说过 IP 地址这个概念,并且我敢保证你现在一定在使用某一个 ip 地址在看我的这篇文章。你可以在百度搜索栏 ip地址 这几个关键词,它的搜索结果会显示出一个本机 ip 地址。这个 ip 就是百度服务器可以找到你的原因,它相当于你家的门牌号,百度就是依靠它把首页的页面返回给你的。
-
聪明的你可能想到了,那对应着百度是不是也应该会有一个 ip 呢?没错,如果你要访问百度,首先你的计算机也得先找得到百度才可以。我们可以在终端输入
ping www.baidu.com
。下面这段 153.3.238.110 就是百度的 ip 地址。 -
其实 153.3.238.110 这串数字才是
www.baidu.com
的真身,你在地址栏上输入的www.baidu.com
最终会被转换成 153.3.238.110 ,然后根据这串数字和百度服务器交互。你可能会去地址栏直接输入这串数字来验证,但是由于现在绝大部分网站都不允许直接 ip 访问,所以你可能会收到一个 403 的警告)
-
上面这个例子中的
www.baidu.com
被我们称为域名(domain name),域名常常需要配合ip
来一起使用。先有域名没有ip
是可以的,也正因为这个特性,也衍生出了抢注域名这个行业。想当初qq.com
这个域名就是腾讯做大以后花了十几万美元从外国人手中买回来的。 -
很显然,相比于记下 153.3.238.110 这段毫无记忆规律的数字来讲,
www.baidu.com
就显得格外亲切。所以域名最大的用处就是帮助人们减轻记忆负担。 -
让我们举一反三,某一天百度服务器升级,需要更新成另外一台不同 ip 的服务器,那么对于用户来讲,我们压根不用考虑百度更换 ip 这件事的,只需要记住
www.baidu.com
就行了,这也是使用域名的优势之一。 -
那么到底谁帮我们做了域名自动转化为 ip 这件事呢?别着急,我们再仔细研究一下域名。
二. 域名的组成
-
我们依旧拿
www.baidu.com
这个域名来分析。其实我们平常拼写的域名有一个很重要但是很不起眼的组成部分: “.” ,其实完整的域名应该是www.baidu.com.
, 注意: 这里的com.
尾部多了一个点,这个点被称为根域名。 什么?一个点就是根域名了?是的,你没听错。根域名服务器是 13个 固定 ip 所组成服务器群的简称。
根域名服务器不保存具体 ip 和完整域名的信息对照表,它保存的只是所有一级域名服务器的 ip 地址信息。 -
上面提到的
.com
,这一段被称为一级(或顶级)域名 ,一级域名服务器同理,也只保存二级域名
的服务器 ip 信息。 -
紧接着就是
.baidu
这一部分被称为二级域名,在此之后,我们对二级域名之后等级的操作,都将由二级域名服务器来进行管理。 -
对,你现在脑子里浮现的结论是对的。
.www
这部分被称为 三级域名,只不过它前面没有四级域名罢了。 -
实际上 DNS 整套体系架构的是类似于下面这样的结构,好像一个树根逐渐向外扩散。
三. 购买域名亲自体验
-
纸上得来终觉浅,不如你花一元来亲自体验一下整个过程,你会对 DNS 有一个全新的理解。
-
由于一些魔法原因,无法演示我在国外的购买方式,但是国内阿里云是一样可以的。
-
百度搜索:
阿里云、域名
关键词即可,我们会来到阿里云的域名购买界面。注册域名第一步就是让你选择一级
域名的字符。你需要在这里先验证你想要注册的域名是否已经被申请了。
-
假如你输入
baidu
,你会发现.com
的一级域名服务器已经保存了baidu
的二级域名相关信息。
我们试着换一个二级域名,如果想购买,方法也很简单,页面上已经写的很清楚了。这里省略如何购买等步骤,(避免有打广告的嫌疑🥱)
-
当你点击购买
pbkfang.com
这个域名,确认付款的一瞬间,背后发生了什么?这是你需要清晰知道的:- 首先阿里云会通知
.com
这个一级域名服务器
,说:“.pbk
这个二级域名
已经被注册了,你们不要再使用了!” - 接着世界各地的
.com
服务器就会互相转告“.pbk不能用了,请互相通知。” 直到所有的.com
一级域名服务器全都知道这个消息。 - 阿里云服务器此时就中保存着对你
xxx.pbkfang.com
的翻译权。(也就是域名转真实 ip 这一步)此时的阿里的 DNS 服务器就被称为pbk.com
的权威域名服务器。 - 以后全世界的人访问
pbk.com
的时候,最终都会走向阿里云这个服务器来进行查询请求。
- 首先阿里云会通知
-
你是否真正购买域名其实不重要,在这一步我主要是想让大家理解为什么域名要从后往前看,不要按照人类直觉从
www
看起。其实www
只不过是很已经被大众认知,大家为了方便自家网站容易被浏览才设置为www
的,其实wwww
、wwxxxyy
任意字母组合都可以,随你喜欢,只不过不容易被大家接受罢了。 -
所以你可能已经看出来了,域名最关键的部分就是 一级域名和二级域名,后面三级四级随你喜欢怎么填写都可以,接下来我将演示为什么是这样的。
三. 域名配置和解析的过程
-
由于我没有购买云服务器,所以只能开启本地的
vite
打包项目,来作为 DNS 解析演示,随后我会在后台配置一个test
的三级域名。 -
我首先
npm run
了一个vite
项目,所以我可以在在局域网下的192.168.124.5:4399
地址访问一个http-server
,浏览器可以即可访问这个项目。
如果你不理解这句话的含义,那么这个过程的基本原理我也写过一篇文章,感兴趣可以查阅
前端代码是如何与后端服务器的交互的 -
我现在在浏览器地址栏输入
test.fffang.lol:4399
。我们分析一下接下来发生的事情(我们暂时忽略所有缓存查询)此时一条DNS
查询的请求将发往你的网关(可以粗略地理解为你家光猫或者路由器)
。- 网关向
根域名
服务器询问.lol 一级域名服务器
的ip
是什么? 根服务器
告诉网关:“.lol服务器的 ip 是 x.x.x.x
”- 网关接着去问
.lol服务器
:“fffang.lol 域名服务器
在哪?” .lol服务器
最后告诉网关,在阿里云的一个 ip 为x.x.x.x
的服务器上- 此时阿里作为你的权威服务器,一定保存着
fffang.lol
的所有域名信息。 - 但由于你并没有配置
.test
这个二级域名的相关信息,所有你的网关没有拿到相关域名的任何信息。 - 此时网关告诉浏览器,“我找了一圈,但是没找到相关 ip 地址信息。”
- 然后浏览器很无奈的返回 502 给你
- 网关向
-
接下来我在后台配置一下 DNS 服务器的相关信息,关于配置的细节问题,这里不过多展开。当我点击保存以后,正确的说法应该是:
在 .fffang.lol 域名下,会多一条 A 类型的记录,记录的名称是 test,所映射的 ipv4 类型地址是 192.168.124.5
-
此时我们再访问一下
test.fffang.lol:4399
,页面已经可以正常展示了。
四. 使用 dig 命令验证
-
这里有一个命令行工具可以帮我们更加清晰的观测到以上发生的一切步骤。
dig +trace test.fffang.lol
这里的 “+” 不能省略,这里我清除了一些无用的数据,打印结果如下:; <<>> DiG 9.10.6 <<>> +trace test.fffang.lol ;; global options: +cmd . 66328 IN NS e.root-servers.net. . 66328 IN NS h.root-servers.net. . 66328 IN NS d.root-servers.net. . 66328 IN NS i.root-servers.net. . 66328 IN NS b.root-servers.net. . 66328 IN NS l.root-servers.net. . 66328 IN NS a.root-servers.net. . 66328 IN NS c.root-servers.net. . 66328 IN NS g.root-servers.net. . 66328 IN NS f.root-servers.net. . 66328 IN NS j.root-servers.net. . 66328 IN NS k.root-servers.net. . 66328 IN NS m.root-servers.net. ;; Received 228 bytes from 192.168.124.1#53(192.168.124.1) in 18 ms lol. 172800 IN NS a.nic.lol. lol. 172800 IN NS b.nic.lol. lol. 172800 IN NS c.nic.lol. lol. 172800 IN NS d.nic.lol. ;; Received 623 bytes from 192.58.128.30#53(j.root-servers.net) in 26 ms fffang.lol. 3600 IN NS coraline.ns.cloudflare.com. fffang.lol. 3600 IN NS cash.ns.cloudflare.com. fffang.lol. 900 IN NSEC fffbaa.lol. NS RRSIG NSEC ;; Received 234 bytes from 212.18.249.146#53(d.nic.lol) in 94 ms test.fffang.lol. 300 IN A 192.168.124.5 ;; Received 60 bytes from 173.245.59.81#53(cash.ns.cloudflare.com) in 206 ms
-
如果你够仔细的话,会发现上面所有关于域名的展示,末尾都加上了一个 “.”。
我接下来会解释一下这串回复的关键信息,请结合上面的代码块的行数继续往下看。
-
第 16 行:dig 尝试向网关的 DNS 服务器查询相关信息,命令首先收到(Received)
192.168.124.1
(我家的光猫)这台服务器上53
端口返回的数据包,包中记录了 13 个根节点的地址信息,对应第3行至15行代码。 -
然后 dig 会同时向这 13 台根服务器发起查询请求,谁最先回应就采用谁的答复。第 22 行代码验证了这件事,表示 dig 最先接收到了来自
j.root-servers.net
这台根服务器的回应。数据内容为: 18-21 行代码。一共有四个a、b、c、d
四台.lol.
的一级域名服务器。 -
然后 dig 继续并发向这四台服务器发起查询请求。在 27 行代码中表明最先收到的回复是来自
d.nic.lol
这台一级域名服务器。 -
紧接着最后一步查询发送给了我的权威域名服务器 cash.ns.cloudflare.com 查询到的结果为第 29 行代码所对应的信息。
test.fffang.lol. 300 IN A 192.168.124.5 ;; Received 60 bytes from 173.245.59.81#53(cash.ns.cloudflare.com) in 206 ms
可以看到,这个信息和我之前在后台配置的数据完全一致。
-
至此 DNS 解析过程结束, dig 返回结果打印到终端上。
五. 思维拓展
-
如果简单用我们前端开发容易理解的方法去思考上面的过程的话,那么就可以用下面这样的代码来表示。首先我们的 DNS 就需要设计成下面的数据结构:
// 抽象的解释 const DNS = { ".root": { 自己本身地址: "0.0.0.0", 一级域名服务器地址: [ { ".lol": { 自己本身地址: "1.1.1.1", 二级域名服务器信息: [ { ".fffang": { 服务器地址: "1.1.1.2", 域名记录: [{ 类型: "A", ip: "192.168.124.5" }], }, }, ], }, }, ], }, };
-
那么查找域名的过程就是:请你设计一个函数,查询 .fffang 这个二级域名的服务器地址,那么你必须得从 root 开始,一层一层查询到 .lol ,最终找到 ffffang 。
-
有没有觉得这个很像一个东西?没错,请打开你项目的路由表结构看一下,这两个有异曲同工之妙。
-
我们在配置路由的时候,也是从
/
路由开始配置,然后就是children
,children
里面又包含子路由,子路由还可以嵌套子路由。那么在页面上输入路由地址的时候,也是/
路径开始,然后输入根路径下的/test/page/index
这样的形式,只不过和的查找顺序域名恰好相反而已。路由是从左到右,域名是从右向左。
六. 关于 DNS 缓存
-
DNS 解析的过程还牵扯到许多缓存的问题,和缓存更新的问题,为了简化主旨内容,在文中并没有涉及到相关内容。
-
浏览器其实本身也会做一层 DNS 缓存,如在 chrome 浏览器输入
chrome://net-internals/#dns
即可查看你浏览器所做的相关 DNS 缓存,它是浏览器查询 DNS 的第一个本地查询点,此时没有任何网络请求产生。
-
当浏览器进程发起的请求发现自身没有缓存后,一条查询请求会发向操作系统本身的存根解析器(Stub resolver),存根解析器也没有查询到后,该请求才会被转发给你的网关(你家的猫或者路由器)。
-
然后运营商接收到这条请求后,也会在自身 DNS 服务器 的缓存中查询,最后不断转发不断查询,直到根服务器,然后一级域名…
文章评论