HandyTools Hub

URL 解析

将任意 URL 拆解为各个组成部分

URL 解析器把任意网址拆成各个组成部分——协议、主机、端口、路径、查询参数和锚点——让你一眼看清或调试它。它面向调试跳转的开发者、检查追踪参数的运营,以及任何想知道一长串 URL 各部分究竟做什么的人。

URL 的组成结构

URL 看起来是一整串字符,但它有 RFC 3986 定义的严格结构。请看:

https://shop.example.com:8080/products/list?page=2&utm_source=newsletter#reviews

从左往右读,各部分为:

部分值含义
协议https浏览器使用的通信方式
主机shop.example.com:8080服务器名加上可选端口
端口8080显式指定;443 和 80 是隐含的、被隐藏
路径名/products/list该服务器上的资源
查询?page=2&utm_source=newsletter查询参数
锚点#reviews页内锚点,从不发送给服务器

知道哪一段是哪一段,排查跳转、追踪 bug 和 API 回调时就轻松得多。

如何阅读结果卡片

最上面一排卡片原样显示解析器存储的协议、主机、端口、路径名、查询和锚点。下面的第二个面板把主机拆成子域名、域名和 TLD。对于上面的例子,主机拆解为:

  • 子域名: shop
  • 域名: example
  • TLD: com

最后一个面板是查询参数表,每个键值占一行,所有百分号编码都解码以便阅读。每张卡片都能单独复制,所以你可以只把路径名取到日志里,或只把端口取到配置文件里。

实操示例:一个营销链接

营销链接最容易让 URL 结构变得混乱。来看:

example.com/lp?utm_source=news&utm_medium=email&utm_campaign=spring%20sale&ref=abc123

因为缺少协议,工具会自动补上 https://。主机变成 example.com,没有子域名,路径是 /lp,参数表为:

  • utm_source = news
  • utm_medium = email
  • utm_campaign = spring sale
  • ref = abc123

注意 spring%20sale 在表里解码成了 spring sale,而原始查询卡片仍显示编码后的字符串。这种拆分很有用:用表来读值,用查询卡片来复制服务器实际收到的字面查询串。

工具如何拆分域名

域名拆分是 URL 解析中没有完美内置答案的部分,因为 co.uk 这类后缀表现得像一个 TLD,实际上却是两个标签。解析器用一份常见多段后缀的小白名单来处理,其余情况走简单回退:

  1. 如果主机名是 IPv4 地址或 localhost,就把整个主机当作域名,没有 TLD。
  2. 否则,把最后一个标签当作 TLD。
  3. 如果主机至少有三个标签,且最后两个构成已知后缀,那么这个两标签后缀成为 TLD,它前面的标签成为域名。

所以 www.example.co.uk 得到子域名 www、域名 example、TLD co.uk。但 www.example.co.za 不在列表上,于是得到子域名 www.example、域名 co、TLD za——技术上是错的,也提醒我们公共后缀逻辑需要比固定列表大得多的数据集。

调试技巧与结构的重要性

URL 是一份接口契约。协议决定浏览器使用哪种通信方式,主机和端口选择服务器,路径选择资源,查询携带应用状态,锚点留在客户端。当其中任何一块发生偏移,故障通常出现在很远的地方——缺少活动数据的分析报告、落到错误路由的 OAuth 回调,或者把两个它认为不同的 URL 分别缓存的 CDN。把地址解析成具名字段,能把模糊的调试变成一份清单:主机对不对、端口是不是你期望的那个、查询键的拼写是否与代码一致、锚点指向的元素是否还存在?

做追踪审计时,粘贴线上 URL,确认预期的参数都在、拼写正确、没有重复——重复的 utm 键是分析数据失真的常见原因。排查跳转链时,逐跳解析并比较路径名和主机;一个多余的结尾斜杠或一个消失的端口,往往就能解释一次意外的 301。做 API 工作时,复制解码后的查询表,在构造签名串之前核对值与文档是否一致,因为百分号解码的差异是签名不匹配的常见来源。

边界情况与常见错误

  • 默认端口会消失。 https://example.com:443/ 归一化后显示空端口,变成 https://example.com/。
  • 国际化域名会变成 punycode。 输入 https://münchen.de,主机名卡片显示 ASCII 形式 xn--mnchen-3ya.de,因为浏览器就是这样为 DNS 存储它的。
  • 结尾斜杠有区别。 即使服务器把它们同等对待,/products 和 /products/ 也是不同的路径名。
  • 空查询不返回任何行。 结尾的 ? 或完全没有查询都会产生空的参数表,而不是空白行。
  • 无效输入会干净地失败。 浏览器无法解析的字符串会显示「Invalid URL」消息,而不是误导性的部分拆解。
  • 把编码值当成真实值。 参数表显示的是解码后的文本,所以搜索 a%26b 会显示为 a&b。需要服务器收到的确切字节时,请看原始查询卡片。
  • 把主机卡片当作域名。 主机包含端口和子域名;域名卡片只是可注册的那个标签。
  • 对每个国家都相信 TLD 拆分。 example.co.za 和 example.com.br 是两级后缀,固定白名单会漏掉,于是域名卡片会误显示为 co 或 com。
  • 忘记路径区分大小写。 即使在同一台服务器上,/Products 和 /products 也可能是不同路由。
  • 把裸词当有效主机。 not a url 会被补上 https://,可能解析得很奇怪;相信结果前先看主机卡片。

相关工具

常见问题

为什么 https://example.com:443 的端口字段是空的?

浏览器的 URL 解析器会归一化掉协议的默认端口。因为 443 是 https 的默认端口(http 是 80),解析器存储的端口为空,卡片就显示一个短横线。像 8080 这样的非默认端口会被保留并显示。

为什么 hello%20world 这样的查询值显示成了空格?

查询参数用标准 URLSearchParams 接口解析,它会对键和值做百分号解码。所以 hello%20world 显示为 hello world,加号也被当作空格。原始查询字符串字段仍然显示编码后的形式。

它如何判断哪部分是域名、哪部分是顶级域名?

它把主机名最后一个标签当作 TLD,然后检查一份固定的已知两段后缀列表——co.uk、com.au、co.jp、co.nz、co.in、org.uk、ac.uk、gov.uk 和 net.au。属于这些后缀时,最后两个标签组成 TLD;列表之外的一律退回到单标签 TLD。

粘贴 mailto: 或 tel: 链接会怎样?

自动补协议这一步只在协议写成「某://」时才识别。因为 mailto: 和 tel: 没有双斜杠,工具会补上 https://,结果就是错的。请自己加上原始协议,或只解析 http、https、ftp 这类分层 URL。

重复的查询键会显示一次还是两次?

每一条都会列出,所以 ?tag=a&tag=b 会产生两行,命名都为 tag。解析器不会把重复项合并成数组——输出表是字符串中实际出现内容的忠实列表。

锚点会被发送到服务器吗?

不会。# 之后的全部内容保留在 hash 卡片里,但从不会在 HTTP 请求中传输。这也是单页应用能从锚点读取路由状态、而服务器从来看不到它的原因。

由 HandyTools Hub 团队审校 · 最后更新