公众号旧文
为什么 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 语法里。
在这些地方 不需要方括号:
pingsship route- DNS AAAA 记录
例如:
ping 2001:4860:4860::8888
只有 URL / URI 需要:
http://[2001:4860:4860::8888]/
六、一句话总结
可以这样记:
IPv4 没有 :,所以直接写。 IPv6 到处都是 :,所以必须用 [] 包起来避免和端口冲突。
扩展阅读: