公众号旧文

为什么 IPv4 可以直接放入URL,但 IPv6 却要加上方括号?

作者:胖子阅读 —

这是很多人第一次看到都会困惑的问题。

核心原因只有一句话:

因为 IPv6 地址里本身就包含 :,而 : 在 URL 里已经被用作“端口分隔符”,所以必须用方括号把 IPv6 地址包起来。

下面用直观的方式来解释。

一、IPv4 在 URL 里的样子

IPv4 地址没有任何歧义,例如:

http://192.168.1.1/

如果要写端口:

http://192.168.1.1:8080/

URL 解析规则很简单:

主机:端口

浏览器看到:

192.168.1.1:8080

就知道:

主机 = 192.168.1.1
端口 = 8080

因为 IPv4 地址里 没有 :,所以不会产生歧义。

二、IPv6 的问题

IPv6 地址长这样:

2001:db8:85a3::8a2e:370:7334

如果直接写进 URL:

http://2001:db8:85a3::8a2e:370:7334:80/

问题来了,浏览器完全不知道:

2001:db8:85a3::8a2e:370:7334:80

到底是:

情况 A

IPv6地址 = 2001:db8:85a3::8a2e:370:7334
端口 = 80

还是:

情况 B

IPv6地址 = 2001:db8:85a3::8a2e:370:7334:80
端口 = 默认端口

因为 IPv6 本身就大量使用 :。

解析器根本分不清。

三、解决办法:RFC 定义方括号

所以在 URL 标准(RFC 3986)里规定:

IPv6 地址必须放在 [] 里面。

正确写法:

http://[2001:db8:85a3::8a2e:370:7334]/

带端口:

http://[2001:db8:85a3::8a2e:370:7334]:80/

解析规则就变成:

[IPv6地址]:端口

浏览器只要看到 ],就知道:

方括号里是完整 IPv6 地址
]后面的:才是端口

四、实际例子

访问 IPv6 本机:

IPv4:

http://127.0.0.1:8080

IPv6:

http://[::1]:8080

::1 是 IPv6 的 localhost。

五、一个很多人不知道的小细节

方括号 只存在于 URL 语法里。

在这些地方 不需要方括号:

  • ping
  • ssh
  • ip route
  • DNS AAAA 记录

例如:

ping 2001:4860:4860::8888

只有 URL / URI 需要:

http://[2001:4860:4860::8888]/

六、一句话总结

可以这样记:

IPv4 没有 :,所以直接写。 IPv6 到处都是 :,所以必须用 [] 包起来避免和端口冲突。

扩展阅读:


你知道127.0.0.1是本机,那127.0.0.2是谁?

为什么IPv6是全球唯一地址,而你家的IPv6却不是固定的?

为什么现在 IP 地址的 .0 和 .255 也能用了?

你每天上网都在使用的IP,是谁分配给你的?