HTTP请求如何工作

113 阅读6分钟

这篇文章描述了浏览器如何使用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.com
  • ns2.dreamhost.com
  • ns3.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

一些最常用的标头字段是。

  • Origin
  • Accept
  • Accept-Encoding
  • Cookie
  • Cache-Control
  • Dnt

但还有很多字段存在。

标头部分由一个空行结束。

请求主体

请求正文是可选的,在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提供的项目。