首页 / 浏览器扩展开发入门教程 / 匹配规则 match_patterns

浏览器扩展开发入门教程

匹配规则 match_patterns

本教程共 56 篇 · 第 17 篇 · 更新于 2026-08-13 · 约 8 分钟阅读

匹配模式match patternsmatchesall_urlshost_permissions内容脚本MV3

本节目标:学完你能准确写出任意范围的匹配模式,知道通配符能放哪不能放哪,也能一眼看出一条模式为什么非法或为什么匹配不上。

匹配模式(match patterns)是一串带通配符的网址,用来描述”一组网址”。内容脚本靠它决定注入哪些页面,宿主权限靠它决定放行哪些站点。这是整个扩展平台里出现频率最高的一种语法,写错一个字符,扩展可能直接加载失败。

17-1 四段结构

一条匹配模式的完整结构是这样的:

<scheme>://<host>:<port>/<path>

其中端口是可选的,其余三段都得有。路径段不能缺省,但允许”带尾斜杠的空路径”——https://*/ 合法,https://example.com(没有斜杠)非法。这四段各有各的规则,我们一段一段拆。

先记一个总原则:匹配模式不是正则,也不是 glob。它只支持 * 这一个通配符,而且 * 出现在哪一段、放在什么位置,规则都不同。别拿正则的直觉去猜。

17-2 scheme:只有四种写法

协议部分必须是下面这几种之一,后面跟冒号加双斜杠:

写法匹配范围
http只匹配 http
https只匹配 https
*只匹配 http 和 https
file匹配本地文件网址

最容易被误解的是 *。很多人以为它是”所有协议”,其实它只覆盖 http 和 https 两个。你想匹配本地文件,必须显式写 file

还有一类协议根本不能写在模式里,比如 about:data:。想让脚本进入这类框架,得靠 content_scriptsmatch_origin_as_fallback 字段,不是靠改协议段。

17-3 host:通配符只能放开头

主机部分有三种合法形式:

  • 完整主机名,比如 www.example.com,只匹配这一个主机。
  • *. 加主机名,比如 *.example.com,匹配 example.com 以及它的所有子域。
  • 单独一个 *,匹配任意主机。

规则的关键约束只有一句:如果用了通配符,它必须是第一个字符或唯一字符,并且后面紧跟一个点(.)或斜杠(/

按这条规则倒推,下面这些写法全是非法的:

  • example.*.com —— 通配符不在开头。
  • *example.com —— 通配符后面不是点或斜杠。
  • www.* —— 同上。

还有一个 Chromium 平台的明确限制:不支持顶级域名通配。也就是说 http://google.*/* 这种”匹配 google 所有国家域名”的写法不存在,你只能一个个列出来:

{
  "matches": [
    "http://google.es/*",
    "http://google.fr/*"
  ]
}
Note

*.example.com 是包含 example.com 本身的,不用再单独补一条 example.com。这点和某些 DNS 通配的语义不同,别多写。

17-4 port 与 path

端口段是可选的。不写的时候,等价于写了 :*,也就是匹配所有端口。所以 http://localhost/* 会匹配 localhost 上的任意端口,本地开发调试时很方便。反过来,如果你显式写了端口,就只匹配那个端口。

路径段必须存在,不能省(https://*/ 这种带尾斜杠的空路径算合法,https://example.com 不带斜杠则非法)。约定俗成的写法是 /*,表示任意路径。有两个细节值得记:

  1. host_permissions 里,路径同样必须写,但它的值会被忽略。所以那儿一律写 /* 就好。
  2. 网址里的 # 片段在匹配之前就被去掉了。所以模式里带片段的写法,比如 https://example.com/#section1,永远匹配不上。

路径匹配还会把查询字符串算进去,这点很容易翻车。比如模式 https://*/path 能匹配 https://example.com/path,但匹配不上 https://example.com/path?foo=1——因为查询字符串让实际路径不再等于 path 了。想连带查询字符串一起匹配,末尾用 /**

Tip

我建议你养成习惯:路径段除了极特殊需求,一律写 /*。想收窄范围优先靠 host 段和 exclude_matches,而不是在路径上抠字符,那样最容易漏匹配。

17-5 合法示例照着抄

下面这几条是官方给的示例模式,覆盖了日常九成需求:

模式含义
https://*/*任意主机的所有 https 页面
https://*/foo*任意主机、路径以 foo 开头的 https 页面
https://*.google.com/foo*bargoogle.com 及其子域、路径以 foo 开头且以 bar 结尾
file:///foo*路径以 foo 开头的本地文件
http://127.0.0.1/*主机为 127.0.0.1 的所有 http 页面
http://localhost/*localhost 的任意端口
*://mail.google.com/*mail.google.com 的 http 与 https 页面

注意 https://*.google.com/foo*bar 这条,路径中间也能放通配符,https://docs.google.com/foobarhttps://www.google.com/foo/baz/bar 都会命中。

17-6 非法写法对照表

写错的模式不会”静默不匹配”,而是会让扩展加载报错。这张表按出错原因整理,对照着自查:

模式问题原因
resource://path/非法协议不在支持列表里
https://example.com非法缺少路径段
https://example.*.com/非法host 里的通配符不在开头
https://*example.com/非法通配符后面不是 ./
http*://example.com/非法协议段的通配符不能和字母混写
*://*非法路径为空,应写成 *://*/*
file://*content_scripts 中非法路径为空,应写成 file:///*;但它在 host_permissions 里会被 Chrome 自动纠正为 file:///*(合法)
https://example.com/#section1匹配不上片段在匹配前已被移除

最后两行值得单独盯一下。file:// 后面是三个斜杠,因为主机段为空,第三个斜杠属于路径。写成两个斜杠是最常见的手误之一。

17-7 <all_urls> 与本地文件的特殊约定

有两个特殊写法不符合上面的四段结构,单独记。

"<all_urls>" 匹配所有以受支持协议开头的网址,等于把合法模式全包了。它写起来最省事,代价也最直接:因为影响所有主机,用了它的扩展在应用商店的审核时间可能会更长。我建议你只在确实需要全网生效时才用。

"file:///*" 让扩展能在本地文件上运行。这个权限比较特殊——即使你在清单里声明了,也需要用户在扩展详情页里手动勾选”允许访问文件网址”才生效。装上就能用是不成立的,功能依赖本地文件的扩展一定要在界面上提示用户去开这个开关。

17-8 同一套语法,很多地方复用

匹配模式不是内容脚本专属的,学一次多处受益。它至少出现在这几个位置:

  • content_scriptsmatchesexclude_matches:决定注入哪些页面。
  • host_permissions:申请对哪些站点的宿主权限(路径写了会被忽略)。
  • web_accessible_resourcesmatches:决定哪些站点能加载你的扩展资源。
  • externally_connectablematches:决定哪些页面能给扩展发消息。
{
  "manifest_version": 3,
  "host_permissions": ["https://api.example.com/*"],
  "content_scripts": [
    {
      "matches": ["https://*.example.com/*"],
      "exclude_matches": ["https://admin.example.com/*"],
      "js": ["content-script.js"]
    }
  ]
}

这段声明的意思是:脚本注入到 example.com 所有子域,但把后台管理子域排除掉;另外单独申请对 api.example.com 的宿主权限,供跨域请求使用。

17-9 写窄一点的三个理由

新手图省事爱写 <all_urls>,我不建议。收窄范围有三个实际好处:

  1. 用户安装时看到的权限提示更温和,愿意装的人更多。
  2. 商店审核更快,被质疑的概率更低。
  3. 脚本不会在无关页面上白跑,页面性能和你的调试体验都更好。

具体做法上,先精确到域名,再用 exclude_matches 剔掉后台、登录、支付这类不该动的页面。改完记得实测:打开一个应该命中的页面和一个不该命中的页面,各看一眼脚本有没有跑。匹配模式这东西凭想象很容易出错,实测两分钟就能定性。

17-10 小结

匹配模式是 <scheme>://<host>:<port>/<path> 四段结构,端口可选,路径必填。协议段的 * 只覆盖 http 和 https;主机段的通配符必须在开头且后跟点或斜杠,且不支持顶级域名通配;路径段习惯写 /*,片段不参与匹配,查询字符串会算进路径。<all_urls>file:/// 是两个特殊约定,前者拖慢审核,后者要用户手动授权。

下一章我们把 run_atworld 两个字段讲透——同样是内容脚本的配置,一个决定”什么时候进场”,一个决定”进场后站在哪个世界”。