“localhost” 和 “127.0.0.1” 有何不同?

Hugehard 2024年08月26日 编辑

在本地进行前端开发调试时,开发者通常会与“localhost”进行交互,通过执行 npm run 命令,便能在浏览器中打开网页,此时地址栏会显示如 http://localhost:xxx/index.html 的链接。

很多人可能就在这样的使用中,并未深究“localhost”与“127.0.0.1”之间的差异。

鉴于我过去与一些同样对这两者区别不甚明了的开发者合作的经验,我觉得有必要普及这方面的知识。

2024-08-26T11:48:00.png

本地主机是什么?

本地主机是一个域名,它与互联网访问中使用的域名在本质上并无不同,只是更易于记忆。

本地主机的使用范围仅限于本地计算机——其名称已经表明:“local”意味着在本地范围内的事物。

无论是约翰·史密斯还是简·多伊,他们都可以在自己的计算机上使用本地主机,而不会相互影响,各自访问自己的网页内容。

从域名到程序的理解

要深入理解本地主机,我们需要探讨用户是如何通过域名来访问程序的,

以谷歌为例进行说明。

1. 当在浏览器中输入 google.com 时,浏览器首先会向 DNS 查询 google.com 的 IP 地址。

为什么需要 IP 地址呢?打个比方,如果有人要给你的公司寄送一个包裹,快递单上会填写公司的地址、名称和收件人等信息。快递的派送过程依赖于这些地址信息,以确保包裹最终送达收件人手中。在网络世界中,域名相当于公司名称,而 IP 地址则相当于公司的具体地址。在网络通信中,IP 地址对于找到对应的程序至关重要。

DNS就像公司的目录,记录了每个域名对应的 IP 地址。有些域名可能尚未注册,导致无法找到其 IP 地址;而有些域名可能对应多个 IP 地址,DNS 会根据特定规则自动返回一个。在购买域名后,域名服务提供商通常会提供 DNS 解析服务,将域名及其对应的 IP 地址登记到 DNS 中。

IP 地址是如何产生的呢?每台联网的计算机都有一个 IP 地址,但个人电脑的 IP 通常不适合供外部访问,这就像公司内部的位置对于内部员工来说很清楚,但对于外部人员则不然。对于谷歌等提供的外部服务,需要一个公共 IP 地址,这通常由互联网服务提供商提供。例如,如果您的公司使用中国联通接入互联网,您可以要求他们为公司的网关服务器分配一个公共 IP 地址。网关服务器就像一个总机,负责处理所有内部网络通信,并设置转发规则,将收到的请求引导到适当的服务器。

2. 有了 IP 地址后,浏览器会向这个地址发送请求。操作系统会将请求打包成 IP 数据包,然后通过网络发送。根据提供的 IP 地址,网络的路由协议会通过多个路由器,最终到达绑定该 IP 的计算机。

3. 一台计算机上可能运行着多个网络应用程序。那么,哪个应用应该接收这个请求呢?这时就需要用到端口了。每个网络应用程序都可以绑定一个或多个端口,系统会避免端口冲突。在请求中指定端口,就能确保请求被发送到正确的网络应用程序。

然而,我们在访问谷歌时通常不需要指定端口。这是因为如果没有特别指定,系统会默认使用 HTTP 的 80 端口和 HTTPS 的 443 端口。启动网络应用程序时,绑定端口是必须的,尽管有些框架会自动在计算机上选择一个未被使用的端口。

“localhost” 和 “127.0.0.1” 有何不同?

基于前面的基础知识,我们可以轻松理解这个问题。

前面提到过,localhost 是一个域名。

那么 127.0.0.1 又是什么呢?它是一个 IP 地址,特指当前计算机的本地 IP 地址,并且只限于此计算机本身使用。您的计算机即使在未连接互联网的情况下也可以使用这个 IP 地址,这对于网络程序的开发和测试极为便利。我们调试的程序正是绑定在这个 IP 地址上的。

需要注意的是,我们通常看到的 IP 地址格式为 X.X.X.X,由点号分隔成四段。实际上,这是一个 32 位的二进制数,被分为四个 8 位的段,然后转换为十进制数以便显示。

那么 localhost 是如何被转换成 127.0.0.1 的呢?它是否需要经过 DNS 解析?答案是不需要。任何计算机都可以在不需要 DNS 解析的情况下使用 localhost 和 127.0.0.1。

这种转换是由每台计算机自行处理的。每台计算机上都有一个 hosts 文件,其中包含了一些固定的 DNS 解析规则,包括将 localhost 转换为 127.0.0.1 的规则,这是一种惯例。

如果您不想使用 localhost,那也完全可以。您可以随意给它起个名字,比如 wodehost,并将其指向 127.0.0.1。

您甚至可以将 google.com 指向 127.0.0.1,但这仅限于您个人的使用,不会影响到其他人。

域名层级结构

localhost 与我们通常见到的域名,比如 www.juejin.cngoogle.comcsdn.net,在结构上有所不同。那么 www、cn、com 和 net 分别是什么意思?为什么 localhost 不需要这些部分?

域名是按照层级来划分的,包括顶级域名(TLDs)、二级域名(SLDs)和三级域名(3LDs)……

顶级域名(TLD):域名系统中的最高层级,位于域名的最右侧,通常由几个字母组成。TLDs 分为通用 TLDs 和国家代码 TLDs,常见的通用 TLDs 包括 .com(用于商业企业)、.net(用于网络提供商)和 .org(用于非营利组织),而国家代码 TLDs 则代表特定的国家或地区,例如 .cn 代表中国,.uk 代表英国。

二级域名(SLD):位于顶级域名之下,由注册者选择并注册,通常是一个个性化且容易记忆的名称。例如,juejin.cn 就是一个二级域名,这通常是我们能够申请的。顶级域名的意义,如 .com、.net 或 .cn,通常被简化,以便于记忆和使用。

三级域名(3LD):位于二级域名之下,常用于指向特定的服务器或子网。在 blog.example.com 中,“blog” 就是一个三级域名。“www” 是最常见的三级域名,通常代表网站的首页或主站点,尽管这只是一种习惯用法,现在很多网站推荐直接通过二级域名进行访问。

按照这个定义,我们可以把 localhost 看作是一个顶级域名,尽管它是一个特殊的、保留的域名,仅用于访问当前计算机。

多个网站共享同一 IP 和端口

如前所述,不同的网络程序不能占用同一端口,但有一些方法可以解决这个问题。

在个人博客盛行的时代,许多人倾向于购买虚拟主机,并部署开源博客平台来发表自己的文章。为了盈利,虚拟主机提供商会在一台计算机上分配多个虚拟主机,让每个人都能通过默认端口 80 访问他们的域名,而且不会出现任何问题。这是怎么做到的呢?

如果您有使用 Nginx、Apache 或 IIS 等网络服务器的经验,您可能对主机头这个概念比较熟悉。主机头实际上就是一个域名。通过设置主机头,我们的程序就可以共享同一个网络端口。

在像 Nginx 这样的网络服务器中部署网站时,我们会配置它将域名包含在主机头中。

启动时,Nginx 和其他网络服务器会占用端口 80。

当一个网站请求到达 Nginx 的端口 80 时,它会根据请求中的域名,识别出配置有相应主机头的网络程序。

然后 Nginx 就会将请求转发给这个网络程序,如果需要的话,还会启动它。

私有 IP 地址

除了 127.0.0.1 之外,还有很多私有 IP 地址,比如常见的 192.168.x.x。这些私有 IP 地址主要供局域网(LANs)内部使用,因为不可能为每台计算机分配一个唯一的 IP 地址。只要在局域网内部没有冲突,这些地址就可以自由使用。比如,您的公司可以使用 192.168.1.1,我的公司也可以使用 192.168.1.1,但如果您想访问我的,就需要通过一个公共 IP 地址。

IPv4 的私有 IP 地址范围通常分为三类:

  • A 类:从 10.0.0.0 到 10.255.255.255
  • B 类:从 172.16.0.0 到 172.31.255.255
  • C 类:从 192.168.0.0 到 192.168.255.255。

这些私有 IP 地址仅限于内部网络使用,不能在公共互联网上使用。

除了上述三个私有 IPv4 地址范围外,还有一些保留的 IPv4 地址范围:

  • 127.0.0.0 到 127.255.255.255 的地址范围用于环回测试,包括问题中提到的 127.0.0.1 地址。您也可以给自己分配一个像 127.0.0.2 这样的 IP 地址,其功能与 127.0.0.1 相同。
  • 169.254.0.0 到 169.254.255.255 的地址范围用于局域网内部。这不太常见;如果您的计算机无法连接到局域网,您可能会看到这个 IP 地址,它被临时分配为局域网地址。

这些地址范围也不能在公共互联网上使用。

还有一些不太常见的专用 IPv4 地址范围。IP 地址范围的完整定义可以在这里找到:www.iana.org/assignments…

IPv6

您可能也听说过 IPv6,这是由于 IPv4 地址空间不足,可用地址数量有限。理论上,IPv6 可以为地球上的每一粒沙子分配一个 IP 地址。尽管 IPv6 已经讨论了许多年,但 IPv4 仍然更广泛地使用。这其中的原因有很多,这里不进行讨论。

IPv6 地址的格式为:XXXX:XXXX:XXXX:XXXX:XXXX:XXXX:XXXX:XXXX。它是一个 128 位长的地址,由冒号分成 8 个段,其中每个 X 代表一个十六进制数(范围从 0 到 F)。IPv6 地址空间比 IPv4 大得多。例如,2001:0db8:3c4d:0015:0000:0000:1a2f:1a2b 是一个有效的 IPv6 地址。

关于 IPv6 的进一步讨论超出了本文的范围,但对此感兴趣的人可以进一步探索。