TL;DR:刚性
最重要的区别是@match 比@include 更加严格和限制性更强,旨在成为更安全的替代方案。出于这个原因,@include 也可能对最终用户产生更可怕的警告;它的整体使用也有点复杂,具体取决于您如何看待它。
这两者的实际用法实际上可以有很大的不同;以下是每种用法的完整细分。
@include(和@exclude)
@include 可能是大多数人更熟悉的指令(以及它的对立双胞胎@exclude,它具有完全相同的语法特征)。这是两者中更强大的指令,主要是因为它可以处理 RegEx 模式(这也意味着它会产生更可怕的警告)。它的用法也是两者中最直接的。
模式
您可以通过两种方式/“模式”指定模式:
全局模式
星号* 可用作wildcard glob,即表示任何个字符,包括零。
For example:
-
@include http://www.example.com/foo/*:
- 匹配
http://www.example.com/foo/ 和 http://www.example.com/foo/bar
-
不匹配
http://www.example.com/baz
还有一种特殊模式可用于专门匹配任何顶级域后缀:.tld。
@include https://www.example.tld/* 之类的模式将与给定域匹配任何顶级域 后缀,例如.com、.org 或.co.uk。
正则表达式模式
以/ 字符开头的@include 指令将被解释为正则表达式,并提供所有标准的JavaScript RegEx 功能:
// ==UserScript==
// @include /^https?://www\.example\.com/.*$/
// @include /^http://www\.example\.(?:org|net)//
// ==/UserScript==
一些注意事项:
- 由于 JavaScript 的 RegEx 解释,正斜杠
/ 不需要在表达式中转义。
-
Other special characters 仍然需要转义。
-
@include 模式始终被视为不区分大小写。
- 不以 EOL 标记
$ 结尾的表达式将隐式允许匹配的尾随字符。
- 换句话说,表达式被视为以
.* 结尾。
-
@include /^https?://www\.google\.com/search/ 将匹配 https://www.google.com/search?q=stackoverflow。
警告
请记住,@include 的强大特性意味着浏览器不能像使用 @match 的脚本那样保证给定脚本的目标;这意味着使用@include 的脚本可能会为用户触发更可怕和更严重的警告。
不使用 @include 的一个常见原因涉及 URL 片段(在哈希 # 字符之后的 URL 部分),以及恶意行为者如何滥用它们在不受欢迎的页面上执行脚本(例如 @ 987654362@ 可以匹配 www.evil.com#www.example.com/),因为 @match 在设计上会忽略片段。
虽然这种攻击在理论上仍然是可能的,但值得牢记的是,一些用户脚本管理器(包括 Tampermonkey)故意完全忽略片段以进行匹配,即使在 @include 指令中也是如此。
@match
@match 指令是 Google for Chrome 的创建,旨在作为 @include 指令的更安全、更沙盒化的版本,内置更多更加严格。
@match 不允许使用 glob 或 RegEx,而是将模式解释为 3 个部分:scheme、host 和 path . Google's documentation 这样描述基本语法:
<url-pattern> := <scheme>://<host><path>
<scheme> := '*' | 'http' | 'https' | 'file' | 'ftp' | 'urn'
<host> := '*' | '*.' <any char except '/' and '*'>+
<path> := '/' <any chars>
模式的每个部分都有自己的注意事项,并且以不同方式解释通配符*。
方案
URL 模式的方案部分必须与支持的方案之一(这似乎取决于浏览器)或通配符 * 完全匹配。
- 在 Chrome 中,即:
http、https、file、ftp 或 urn。
-
In Firefox,这似乎是
http、https、file、ftp、ws、wss、data 或 (chrome-)extension。
在这部分模式中,通配符*完全匹配http或https(MDN mentions,它也可能匹配WebSocket方案ws和wss在某些情况下浏览器)。
主机
URL 模式的主机部分可以有三种样式:
- 完全明确:
www.stackoverflow.com
- 子域通配符:
*.stackoverflow.com
- 完全通配符:
*
顶级域后缀不能是通配符(例如www.stackoverflow.*); this is disallowed for security reasons。为了匹配多个 TLD 后缀,脚本需要为每个后缀包含一个特定的 @match 指令。
路径
URL 模式的路径部分是三种模式中最宽松的,因为唯一的规则是它必须以正斜杠 / 开头。其余的可以是字符和通配符的任意组合。
在本节中,通配符 * 充当标准 glob 运算符,仅匹配 0 个或多个字符。
与模式的路径部分匹配的值正式地是 URL 路径 加上 URL 查询字符串(例如,在 google.com/search?q=test 中,查询字符串是q=test),包括?之间。对于旨在匹配给定域末尾的模式来说,这是一个潜在的陷阱,因为它们可能会被添加的查询字符串所破坏。
另请注意,路径不包含 URL 片段(URL 末尾的部分,在哈希 # 之后,例如 www.example.com#main); @match 指令在设计上会忽略 URL 片段,以防止滥用无意匹配。
注意事项
这是相当明显的,但需要重复的是,脚本应该小心@include完全和完全脚本打算在其上运行的 URL。失控脚本的范围可以从无法检测到的轻微烦恼到重大问题;始终仔细检查脚本是否仅在它们应该在的地方运行,并在必要或方便时使用@exclude 添加护栏。