URLPattern exec 怎样提取命名路由参数
来源:17golang原创
时间:2026-11-15 01:35:13 461浏览 收藏
如果只想从浏览器原生 URL 模式中取出 /books/:id 里的 id,关键写法是读取 URLPattern.exec() 返回对象的 pathname.groups。匹配成功时这里保存命名组;匹配失败时整个返回值是 null,不能直接链式访问。
官方资料:https://developer.mozilla.org/en-US/docs/Web/API/URLPattern/exec
先记住三个边界:
exec()返回的是匹配结果对象或null,不是布尔值。:id这样的命名组会出现在对应 URL 部分的groups.id中。- 相对 URL 需要配合
baseURL才能解析成可匹配的绝对地址。
先看 exec 的返回结构
URLPattern 会把协议、主机、路径、查询和哈希拆成独立结果字段。本文只关心路由最常用的 pathname:它包含实际匹配到的路径文本,以及命名组和值。
const pattern = new URLPattern({ pathname: '/books/:id' });
// exec 匹配成功后返回按 URL 部分组织的对象。
const match = pattern.exec('https://example.com/books/123');
// 命名组 id 的值位于 pathname.groups.id。
console.log(match.pathname.groups.id); // '123'
// 不匹配时返回 null,调用属性前必须先判断。
const missing = pattern.exec('https://example.com/authors/123');
console.log(missing === null); // true
这里的 id 不是从完整字符串上用正则再次截取,而是由 URLPattern 按 pathname 的模式放入结果对象。这样可以把“哪一段 URL 被匹配”和“命名参数是什么”放在同一个返回结构里。

用命名组匹配绝对 URL
实际路由通常不止一个参数。可以在同一个 pathname 模式中声明多个命名组,再从 groups 对象读取它们。命名组名称应保持稳定,后续业务代码只依赖这些名称,不要依赖未命名组的数字下标。
const detailPattern = new URLPattern({
// 两个冒号开头的片段分别命名为 category 和 id。
pathname: '/:category/:id',
});
function readRoute(url) {
// 匹配失败时返回 null,先保存结果再做分支处理。
const result = detailPattern.exec(url);
if (!result) return null;
// 只从 pathname.groups 读取路由参数,避免把 query 当成路径参数。
return {
category: result.pathname.groups.category,
id: result.pathname.groups.id,
};
}
console.log(readRoute('https://example.com/books/123'));
// { category: 'books', id: '123' }
console.log(readRoute('https://example.com/books'));
// null
如果同一个 URL 还带有查询参数,查询部分会出现在 result.search,不会自动混入 pathname.groups。因此,路径参数、查询参数和哈希值应分别处理。
处理相对 URL 和 baseURL
页面路由代码经常拿到的是 /books/123 这样的相对路径。此时可以把基准站点作为第二个参数传给 exec(url, baseURL)。相对 URL 没有基准地址时,无法完成绝对 URL 解析,结果不会按预期匹配。
const pattern = new URLPattern('/books/:id', 'https://example.com');
// 相对路径和 baseURL 一起使用,可以得到完整匹配结果。
const result = pattern.exec('/books/123', 'https://example.com');
console.log(result?.pathname.groups.id); // '123'
// 绝对 URL 也可以直接传入,不需要额外的 baseURL。
const absolute = pattern.exec('https://example.com/books/456');
console.log(absolute?.pathname.groups.id); // '456'
要注意参数位置:字符串 URL 可以配合 baseURL;如果传入的是包含 pathname 等字段的输入对象,就不应再额外传第二个基准地址。把两种调用形式混用,容易得到 TypeError。

补上未匹配和字段边界
推荐把 exec() 当成“返回数据或空值”的函数,而不是把它当成 test() 那样的布尔判断。需要只判断是否匹配时可以使用 test();需要读取路由参数时才使用 exec()。
function matchBook(url) {
// 先处理 null,再访问 pathname,避免未匹配时抛出异常。
const result = pattern.exec(url);
if (result === null) {
return { matched: false };
}
// input 是当前 URL 部分的原始匹配文本,groups 才是命名参数集合。
return {
matched: true,
path: result.pathname.input,
id: result.pathname.groups.id,
};
}
速查可以这样记:
| 目标 | 读取位置 | 边界 |
|---|---|---|
| 判断是否匹配 | pattern.test(input) | 只得到布尔结果 |
| 读取路径参数 | result.pathname.groups | 先排除 null |
| 匹配相对路径 | exec(url, baseURL) | 基准地址必须可解析 |
| 读取原始路径 | result.pathname.input | 它不是命名组对象 |
相关问题
URLPattern.exec 没匹配到时返回什么?返回 null。读取 pathname.groups 前应先判断结果是否为空。
命名参数应该从哪里取?例如模式是 /:id,匹配成功后从 result.pathname.groups.id 读取。
相对 URL 为什么需要 baseURL?相对路径本身缺少协议和主机,baseURL 用来提供解析所需的基准。
什么时候使用 test 而不是 exec?只需要真假判断时用 test();还要拿路径、命名组或其他 URL 部分时用 exec()。
最终可以把它归纳成一句话:先用 URLPattern 描述 URL 部分,再用 exec() 取得结构化结果,命名路由参数从对应部分的 groups 读取,未匹配和相对地址则分别用 null 判断与 baseURL 处理。
-
Golang · Go教程 | 4个月前 | 前端开发 · Go教程 · html/template · Go html/template CurrentPath 导航高亮 template.FuncMap Go网页模板409 收藏
-
306 收藏
-
194 收藏
-
427 收藏
-
480 收藏
-
文章 · 前端 | 15分钟前 | javascript · web安全 · 前端开发 · 浏览器API · writeText Permissions Policy Clipboard API clipboard-write 安全上下文 用户激活390 收藏
-
文章 · 前端 | 18分钟前 | html · javascript · 前端开发 · 可访问性 · 浏览器API · JavaScript 模态对话框 ::backdrop HTML dialog showModal inert top layer160 收藏
-
文章 · 前端 | 29分钟前 | javascript · 前端开发 · 浏览器API · @import Shadow DOM CSSStyleSheet replaceSync Constructable Stylesheets333 收藏
-
348 收藏
-
文章 · 前端 | 39分钟前 | RTCDataChannel bufferedAmount bufferedAmountLowThreshold bufferedamountlow WebRTC背压471 收藏
-
253 收藏
-
172 收藏
-
321 收藏
-
文章 · 前端 | 47分钟前 | javascript · 前端开发 · 浏览器API · localStorage sessionStorage storage事件 Web Storage 同源文档200 收藏
-
424 收藏
-
文章 · 前端 | 53分钟前 | 前端 · javascript · Web API Fetch AbortController AbortSignal abort(reason) signal.reason318 收藏
-
491 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 立即学习 543次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 立即学习 516次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 立即学习 500次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 立即学习 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 立即学习 485次学习