Back

URLPattern API:以现代方式匹配 URL

URLPattern API:以现代方式匹配 URL

如果你曾经编写过正则表达式来从 URL 路径中提取用户 ID,你一定知道那种痛苦。模式开始时很简单,然后逐渐演变成一团充满转义字符和捕获组的难以阅读的混乱代码。当需求发生变化时,你不得不调试正则表达式,而不是专注于构建功能特性。

URLPattern API 提供了一种更好的方法。它是一个用于现代 URL 匹配的 WHATWG 标准,可以在浏览器中原生运行,让你使用可读的模式而不是晦涩的正则表达式来匹配和解析 URL。本文介绍了 URLPattern 解决的问题、其核心概念,以及前端开发者何时应该使用它。

核心要点

  • URLPattern 是一个 WHATWG 标准,提供可读、可维护的 URL 匹配功能,无需复杂的正则表达式
  • 该 API 使用命名参数(如 :id)而不是位置捕获组,使提取的数据具有自文档化特性
  • URLPattern 可以匹配完整的 URL 或单个组件(协议、主机名、路径名、查询字符串、哈希等)
  • 浏览器支持在 2025 年末达到基线新可用状态,Chrome、Edge、Firefox 和 Safari 均支持
  • 最适合用于 Service Worker、自定义 SPA 路由逻辑和 URL 驱动的 UI 状态——不能作为完整路由框架的替代品

URLPattern 解决了什么问题?

在 URLPattern 出现之前,开发者解析 Web URL 主要有两种选择:编写自定义正则表达式或引入路由库。

正则表达式可以工作,但会造成维护困难。像 /^\/users\/([a-zA-Z0-9]+)\/?$/ 这样的模式,每次重新查看时都需要进行心理解析。捕获组是位置性和匿名的——如果添加新的段,现有代码就会出错。

路由库解决了可读性问题,但会增加打包体积并引入特定框架的语法。你的 URL 匹配逻辑会与特定工具绑定。

URLPattern 提供了一个标准化的中间方案。它使用从流行路由约定中借鉴的直观语法:

const pattern = new URLPattern({ pathname: '/users/:id' })

:id 段是一个命名组。没有转义字符。没有编号的捕获组。该模式读起来就像它匹配的 URL 结构。

URLPattern API 的核心概念

模式可以匹配完整 URL 或单个组件

URLPattern 可以匹配完整的 URL 或特定组件。URL 分解为八个部分:协议(protocol)、用户名(username)、密码(password)、主机名(hostname)、端口(port)、路径名(pathname)、查询字符串(search)和哈希(hash)。

你可以为任意组合定义模式:

const pattern = new URLPattern({
  hostname: '*.example.com',
  pathname: '/api/:version/*'
})

这会匹配 example.com 的任何子域名以及 API 路径。未指定的组件默认为通配符,匹配任何内容。

测试与提取结构化组

URLPattern 提供两个主要方法,具有不同的用途。

test() 方法返回布尔值——此 URL 是否匹配该模式?

pattern.test('https://api.example.com/api/v2/users') // true

exec() 方法返回详细的匹配结果,包括捕获的组:

const result = pattern.exec('https://api.example.com/api/v2/users')
console.log(result.pathname.groups.version) // 'v2'

命名组成为对象属性。不再需要访问 result[1] 并希望索引是正确的。

浏览器对 URLPattern 的支持

URLPattern 在 2025 年末达到基线新可用状态。Chrome、Edge、Firefox 和 Safari 都支持它。这不再是实验性功能或仅限 Chrome 的 API——它是一个可以在生产环境中使用的稳定 Web 标准。

对于服务器端 JavaScript,情况有所不同。最新的 Node.js 23+ 版本包含 URLPattern,但根据官方文档,该实现仍处于实验阶段。如果你编写的代码在两种环境中运行,需要单独验证 Node.js 的行为与浏览器预期的差异。

何时使用 URLPattern

URLPattern 作为低级原语表现出色,而不是完整的路由解决方案。适用于以下场景:

Service Worker,需要拦截请求并根据 URL 模式应用不同的缓存策略。

SPA 路由逻辑,当你构建自定义导航处理或需要在框架路由器之外进行 URL 匹配时。

URL 驱动的 UI 状态,当组件需要解析当前 URL 并提取参数时。

URLPattern 不会取代 React Router 或 Vue Router。这些框架提供导航守卫、懒加载以及与组件生命周期的集成。URLPattern 只做好一件事:根据模式匹配 URL 并提取数据。

实际对比

考虑从 /products/electronics/123 中提取类别和 ID。

使用正则表达式:

const match = /^\/products\/([^/]+)\/(\d+)$/.exec(pathname)
const category = match?.[1]
const id = match?.[2]

使用 URLPattern:

const pattern = new URLPattern({ pathname: '/products/:category/:id' })
const result = pattern.exec({ pathname })
const { category, id } = result?.pathname.groups ?? {}

URLPattern 版本更长,但具有自文档化特性。六个月后,你无需解码正则表达式就能理解它的作用。

总结

URLPattern 通过清晰、可读的语法在浏览器之间标准化了 URL 匹配。它无需正则表达式的复杂性就能提取命名参数,并且无论你是匹配路径名、主机名还是完整 URL,都能保持一致的工作方式。

对于构建 SPA、Service Worker 或任何 URL 驱动功能的前端开发者来说,URLPattern 提供了一个面向未来的基础。查看 MDN 的 URLPattern 文档获取完整的语法参考,并开始用可维护的方案替换那些正则表达式模式。

常见问题

URLPattern 可以匹配 URL 的 search 组件,但将其视为原始字符串。对于像 ?page=2&sort=name 这样的查询参数,URLPattern 可以针对 search 字符串匹配模式,但在匹配后仍需要使用 URLSearchParams 来解析单个键值对。

支持。你可以使用问号修饰符使段变为可选。例如,/users/:id? 可以同时匹配 /users 和 /users/123。当 URL 中不存在可选段时,命名组将为 undefined。

默认情况下,URLPattern 将尾部斜杠视为有意义的。/users/:id 的模式不会匹配带有尾部斜杠的 /users/123/。要同时匹配两者,可以使用带有适当修饰符的可选尾部斜杠模式,如 /users/:id/,或为两种变体创建模式。

有的。urlpattern-polyfill 包为缺少原生实现的浏览器和 Node.js 版本提供 URLPattern 支持。根据特性检测有条件地导入它,以避免在具有原生支持的环境中加载不必要的代码。

Understand every bug

Uncover frustrations, understand bugs and fix slowdowns like never before with OpenReplay — the open-source session replay tool for developers. Self-host it in minutes, and have complete control over your customer data. Check our GitHub repo and join the thousands of developers in our community.

OpenReplay