Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

URI和DNS #17

Open
dark9wesley opened this issue Apr 26, 2021 · 0 comments
Open

URI和DNS #17

dark9wesley opened this issue Apr 26, 2021 · 0 comments
Labels

Comments

@dark9wesley
Copy link
Owner

dark9wesley commented Apr 26, 2021

URI/URL

严格来说,URI并不等于网址,在HTTP的世界里,URL才代表网址。但因为URL是在太普及了,所以常常把这两者简单视为相等。

URI的格式

URI本质上是一个字符串,作用是唯一的标记资源的位置和地址。

URI由四部分组成,分别是:

  1. scheme :协议名,表示资源应该用哪种协议来访问。在scheme之后,必定是三个特定字符“://”,用来分隔scheme和后面的部分。
  2. host:port :资源所在的主机名和端口号,主机名可以是IP或者域名的形式,必须要有,但端口号可以省略。
  3. path :资源所在位置的路径,URI的path必须以“/”开始,也就是包含“/”。
  4. query :查询参数。在path之后,用一个“?”开始,但不包含“?”,是多个key=value的字符串,这些KV值用字符“&”连接。

URI的编码

由于在URI里只能使用ASCII码,如果想要在URI里使用英语以外的语言,或者有某些特殊的URI在path,query里使用“@&?”等起界定符作用的字符,那么必定会导致URI解析出错,这时该怎么办呢?

所以URI引入了编码机制,对于ASCII码以外的字符集和特殊字符,会将它们转换为与URI语义不冲突的形式。

转义的规则很简单粗暴,直接把非ASCII码或特殊字符转换成十六进制字节值,然后前面再加上一个“%”。

encodeURI和encodeURIComponent的区别

encodeURI和encodeURIComponent都是对URI的编码,唯一区别就是编码的字符范围了。

  • encodeURI一般用来编码整个URI,它假定URI中的任何保留字符都有特殊意义,所有不会编码它们。
  • encodeURIComponent一般用来编码组成URI的个别部分,它假定任何保留字符都代表普通文本,所以必须编码它们。

DNS

IP协议的职责是“网际互联”,它位于MAC层之上,使用IP地址将MAC编号转换为了4组数字。

只要每个小网络在IP地址这个概念上达成一致,不管它在MAC层有多大差异,都能接入TCP/IP协议栈,最终汇入互联网中。

随着接入互联网的设备越来越多,IP地址对人不友好的问题也随之暴露,主要是难以记忆。

DNS域名系统就是为了解决这个问题而生,它是对IP地址的一层抽象,将数字形式的IP地址转换为更有意义,更好记忆的字符串。

域名的形式

域名是一个有层次的结构,是一串用“.”分隔的多个单词,最右边的被称为顶级域名,紧接着的就是二级域名。层级关系从右到左依次降低。

最左边的是主机名,一般会用来表示主机的用途,例如“www”就表示提供万维网服务,“mail”就表示提供邮件服务。

域名本质上是一个名字空间系统,使用多级域名能很好的划分出不同的国家、地区、公司、部门,每个域名都是独一无二的。

域名的解析

就像IP地址必须被转换为MAC地址才能访问主机一样,域名也必须转换为IP地址,这个过程就是域名解析。

DNS的核心系统是一个三层的树状、分布式服务,基本对应域名结构:

  1. 根域名服务器:管理顶级域名服务器,返回顶级域名服务器的IP地址。
  2. 顶级域名服务器:管理各自域名下的权威域名服务器。
  3. 权威域名服务器:管理自己域名下主机的IP地址。

有了这个系统后,每个域名都能通过这个树形结构从顶向下进行查询,就像把域名从右向左顺序走了一遍,最终获得域名对应的IP地址。

例如,要访问“www.apple.com”这个网站,就要进行下面的三次查询:

  1. 访问根域名服务器,它会告知“com”这个顶级域名的IP地址。
  2. 访问“com”顶级域名服务器,它会告知“apple.com”权威域名服务器的地址。
  3. 最后访问“apple.com”权威域名服务器,就得到了“www.apple.com”的地址。

域名的缓存

虽然核心的DNS系统遍布全球,服务能力很强也很稳定,但如果全部网民都往里挤,整个系统即使不会崩溃,也会很慢。

所以为了缓解DNS系统域名解析的压力,就不能让所有人往里挤。

目前有两种手段,基本都围绕着“缓存”这个概念。

  1. 自建DNS服务器
    很多大公司、网络运行商都会建立自己的DNS服务器,作为用户DNS查询的代理商,代表用户访问核心DNS系统。

这些自建的DNS服务器会缓存之前的查询结果,如果已经有了记录,就无需再发起查询,直接返回对应的IP地址。

  1. 操作系统的DNS缓存
    如果之前访问过一个网站,那么这个网站的DNS解析结果就会保存在操作系统的缓存中,无需再去DNS服务器去问。

另外操作系统还有一个特殊的“主机映射”文件,这是一个可编辑的文本。在 Linux里是“/etc/hosts”,在 Windows 里是“C:\WINDOWS\system32\drivers\etc\hosts”。

如果操作系统在缓存里找不到DNS记录,就会来找这个文件。

有了这几种缓存之后,核心DNS系统的压力就减轻了很多。

总结来说,一个DNS查询会经历这么几个过程:

  1. 查找浏览器缓存中的DNS记录,找到则直接返回。
  2. 查找操作系统中的DNS记录,找到则直接返回。
  3. 查找操作系统中的host文件的DNS记录,找到则直接返回。
  4. 查找DNS代理服务器中的DNS记录,找到则直接返回。
  5. 访问核心DNS服务器,进行DNS解析,返回IP地址。
@dark9wesley dark9wesley changed the title TCP/IP四层模型与OSI七层模型 TCP/IP四层模型与OSI七层模型 May 9, 2021
@dark9wesley dark9wesley changed the title TCP/IP四层模型与OSI七层模型 URI和DNS May 10, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant