这篇文章描述了浏览器如何使用HTTP/1.1协议执行页面请求。
如果你曾经做过一次面试,你可能会被问到。"当你在谷歌搜索框中输入东西并按下回车键时会发生什么"。
这是你被问到的最多的问题之一。人们只是想看看你是否能解释一些相当基本的概念,以及你是否了解互联网的实际运作。
在这篇文章中,我将分析当你在浏览器的地址栏中输入一个URL并按下回车键时会发生什么。
在一篇博文中,这是一个非常有趣的话题,因为它涉及到许多技术,我可以在不同的文章中深入探讨。
这是一项很少改变的技术,它为人类有史以来最复杂、最广泛的生态系统之一提供动力。
HTTP协议
首先,我特别提到HTTPS,因为事情与HTTPS连接是不同的。
我只分析URL请求
现代浏览器有能力知道你在地址栏中写的东西是一个实际的URL还是一个搜索词,如果它不是一个有效的URL,它们将使用默认的搜索引擎。
我假设你输入了一个实际的URL。
当你输入URL并按下回车键时,浏览器首先建立完整的URL。
如果你只是输入了一个域名,如flaviocopes.com ,浏览器默认会在它前面加上HTTP:// ,默认为HTTP协议。
与macOS / Linux有关的事情
仅供参考。Windows可能会对一些事情的处理方式略有不同。
DNS查询阶段
浏览器开始进行DNS查询,以获得服务器的IP地址。
域名对我们人类来说是一个方便的快捷方式,但互联网的组织方式是,计算机可以通过其IP地址查找服务器的确切位置,这是一组数字,如222.324.3.1 (IPv4)。
首先,它检查DNS本地缓存,看看该域名最近是否已经被解决。
Chrome有一个方便的DNS缓存可视化工具,你可以在chrome://net-internals/#dns看到。
如果在那里没有发现,浏览器就会使用DNS解析器,使用gethostbyname POSIX系统调用来检索主机信息。
gethostbyname
gethostbyname 首先查找本地主机文件,在macOS或Linux上,该文件位于 ,以查看系统是否在本地提供了该信息。/etc/hosts
如果没有提供任何关于域名的信息,系统会向DNS服务器发出请求。
DNS服务器的地址存储在系统首选项中。
这些是2个流行的DNS服务器。
8.8.8.8:谷歌公共DNS服务器1.1.1.1:CloudFlare DNS服务器
大多数人使用他们的互联网供应商提供的DNS服务器。
浏览器使用UDP协议执行DNS请求。
TCP和UDP是计算机网络的两个基础协议。它们处于相同的概念层面,但TCP是面向连接的,而UDP是一个无连接的协议,更轻巧,用于发送信息,开销很小。
如何进行UDP请求不在本教程的范围内
DNS服务器的缓存中可能有该域名的IP。如果没有,它将询问根DNS服务器。那是一个驱动整个互联网的系统(由13个实际的服务器组成,分布在地球上)。
DNS服务器不知道地球上每一个域名的地址。
它所知道的是顶级DNS解析器的位置。
一个顶级域名是域名的扩展。.com,.it,.pizza 等等。
一旦根DNS服务器收到请求,它就将请求转发到该顶级域名(TLD)DNS服务器。
假设你正在寻找flaviocopes.com 。根域DNS服务器返回.com顶级域名服务器的IP。
现在,我们的DNS解析器将缓存该顶级域名服务器的IP,因此它不必再向根DNS服务器查询。
TLD DNS 服务器将拥有我们正在寻找的域名的权威性域名服务器的 IP 地址。
怎么会这样?当你购买一个域名时,域名注册商会向域名服务器发送适当的TDL。当你更新名称服务器时(例如,当你改变主机提供商时),这些信息将由你的域名注册商自动更新。
这些是主机提供商的DNS服务器。它们通常不止一个,以作为备份。
比如说。
ns1.dreamhost.comns2.dreamhost.comns3.dreamhost.com
DNS解析器从第一个开始,并试图询问你正在寻找的域名(包括子域名)的IP。
这就是IP地址的最终真实来源。
现在我们有了IP地址,我们可以继续我们的旅程了。
TCP请求握手
有了服务器的IP地址,现在浏览器可以启动一个TCP连接。
TCP连接在完全初始化之前需要进行一些握手,然后才能开始发送数据。
一旦连接建立,我们就可以发送请求了
发送请求
请求是一个纯文本文件,其结构是由通信协议决定的精确方式。
它由3个部分组成。
- 请求行
- 请求头
- 请求正文
请求行
请求行设置,在一个行上。
- HTTP方法
- 资源位置
- 协议版本
例子。
请求头
请求头是一组设置某些值的field: value 对。
有2个强制字段,一个是Host ,另一个是Connection ,而其他字段都是可选的。
Host: flaviocopes.com
Connection: close
Host 表示我们想要的目标域名,而 总是被设置为 ,除非连接必须保持开放。Connection close
一些最常用的标头字段是。
OriginAcceptAccept-EncodingCookieCache-ControlDnt
但还有很多字段存在。
标头部分由一个空行结束。
请求主体
请求正文是可选的,在GET请求中不使用,但在POST请求中非常常用,有时也用于其他动词,它可以包含JSON格式的数据。
因为我们现在分析的是一个GET请求,所以请求正文是空白的,我们不会再去研究它。
响应
一旦请求被发送,服务器就会对其进行处理并发回一个响应。
响应以状态代码和状态信息开始。如果请求成功并返回200,它将以。
请求可能会返回一个不同的状态代码和信息,比如这些。
404 Not Found
403 Forbidden
301 Moved Permanently
500 Internal Server Error
304 Not Modified
401 Unauthorized
然后,响应包含一个HTTP头的列表和响应体(因为我们是在浏览器中发出请求,所以它将是HTML)
解析HTML
浏览器现在已经收到了HTML,并开始解析它,而且会重复我们对页面所需的所有资源所做的完全相同的过程。
- CSS文件
- 图像
- 图标
- JavaScript文件
- ...
浏览器如何渲染页面就不在本文讨论范围之内了,但重要的是要明白,我所描述的过程不仅仅是针对HTML页面,而是针对任何通过HTTP提供的项目。