# 前端路由规则想写成模式，URLPattern 能匹配到哪一层？

**URL:** <https://www.shiqidu.com/t/topic/2057>\
**Category:** 开发调优\
**Tags:** 问与答, JavaScript, 前端开发, 浏览器, API\
**Created:** [2026 年11 月 13 日 04:19 UTC](https://www.shiqidu.com/t/topic/2057 "2026-11-13T04:19:22Z")\
**Posts on this page:** 1\
**Page:** 1

<div class="post-metadata">

作者： ![shiqidu\_editor](https://www.shiqidu.com/user_avatar/www.shiqidu.com/shiqidu_editor/32/528_2.png) [@shiqidu\_editor](https://www.shiqidu.com/u/shiqidu_editor)\
发布日期： [2026 年11 月 13 日 04:19 UTC](https://www.shiqidu.com/t/topic/2057/1 "2026-11-13T04:19:22Z")

</div>

路径里有 id、通配后缀，有时还要看 hostname，自己 split 几次很容易漏边界。结尾要不要斜杠、大小写算不算同一条，这些细节用手写判断也容易对不齐。要判断一段 URL 能不能对上某条路由模式，并不想为此手写一堆字符串切割。

[URL Pattern API](https://developer.mozilla.org/en-US/docs/Web/API/URL_Pattern_API) 定义了一套用来创建 URL 模式匹配器的语法，可以拿完整地址或单个分量去比对。[URLPattern](https://developer.mozilla.org/en-US/docs/Web/API/URLPattern) 就是这套接口：`test()` 只回答命中没命中，`exec()` 返回匹配到的各部分，对不上则是 `null`。语法来自 path-to-regexp，模式里可以写字面量、通配符（`/posts/*`）、命名分组（`/books/:id`），以及用花括号包起来的非捕获分组。MDN 的例子里，`new URLPattern({ pathname: "/books/:id" })` 去对 `https://example.com/books/123` 时，`test()` 为 true，`exec()` 得到的 `pathname.groups` 是 `{ id: "123" }`。路径分量里，分组默认会匹配除 `/` 以外的字符。主机名里则默认不吃掉 `.`。分组还可以加修饰符：`?` 表示可有可无，`+` 至少重复一次，`*` 可以重复零次或多次。未命名的正则分组会按出现顺序编成数字键。

构造时既可以传分量对象，也可以传带模式的完整 URL 字符串，再配可选的基础 URL。对象写法里没写的分量默认是通配符 `*`，所以只写 `hostname` 时，协议和路径不会把匹配卡死。传入基础地址之后，若输入里写了路径但没写协议和主机，协议、主机和端口可以从那里补上，查询和 hash 则不会补。用户名和密码也不会被继承。输入里一旦写了协议，就不会再从基础地址补其它分量。反过来，路径默认不会自动忽略末尾斜杠：`/books` 对不上 `/books/`，两边都要收的话，官方的写法是 `/books{/}?`。默认按大小写敏感来比对，构造函数可以打开 `ignoreCase`。通配符 `*` 本身是贪婪的，会尽量吃掉更长的一段。这和分组默认的非贪婪匹配不一样，写后缀模式时要想一下停在哪。也可以把模式写成完整地址字符串，MDN 举过 `https://cdn-*.example.com/*.jpg` 这类例子：协议和主机、路径一起写进构造函数，未写出的用户名、查询和 hash 会落到通配。只想拦某一类路径时，不必把协议和主机都写死。对象写法里只填 `pathname` 就够了。

它能管到的层是地址的各个分量：`protocol`、`hostname`、`port`、`pathname`、`search`、`hash`，以及 `username`、`password`。`exec()` 按分量交出匹配文本和分组，并不是只给一条路径字符串。未写出、也没有从基础 URL 继承到的模式分量默认是 `*`，测试地址上缺的分量则默认空字符串。因此只写了 `pathname` 时，`search` 也会落到通配，地址后面带不带查询都可能命中，这和手写「只判断路径」时的直觉不一定一样。模式里如果用了正则分组，`hasRegExpGroups` 会标出来，某些调用方不允许这类分组，需要提前看这个标记。浏览器支持方面，MDN 把它标成 Baseline 2025、Newly available，从 2025 年 9 月起在最新设备和浏览器中可用，更老的环境可能没有。

这和站内写过的 [Import Maps](https://www.shiqidu.com/t/topic/2030) 不是同一层：那份管的是模块路径怎么映射，这里是按模式去匹配一段 URL。它也不是某个框架路由器的替代品，只是浏览器提供的匹配器和分组提取。应用层怎么根据命中结果切页面、要不要再包一层自己的路由表，仍然是业务自己的选择。它只回答「对得上对不上、分组是什么」，并不负责把结果画成页面。

你们是只匹配 pathname，还是连 hostname 和查询字符串一起写进模式？
