如何检测哪个用户脚本管理器是 运行 脚本

How to detect which userscript manager is running the script

我正在编写的用户脚本中使用一个函数,由于 Greasemonkey 的限制,该函数在 Greasemonkey 中不起作用。此函数对于用户脚本的正确操作不是必需的,但它可以改善用户体验,所以我不想完全删除它。

我尝试使用 try { ... } catch() { ... } 块,但不幸的是,Greasemonkey 在尝试执行函数时立即停止执行脚本,而不是抛出异常。所以我决定在通过 Greasemonkey 加载脚本时阻止函数的执行,但我一直找不到这样做的方法。

如何检测活动的用户脚本管理器是否为 Greasemonkey?

与列表中的第三项一样,您可以选择 Greasemonkey 不支持但支持您的功能的用户脚本管理器支持的功能。

this comparison table我们可以看出@author元属性不受Greasemonkey支持,但Tampermonkey和Violentmonkey支持。这意味着如果您设置了@author 元 属性,您可以通过 GM_info.script.author.

检查它是否存在
// ==UserScript==
// @name         Greasemonkey Check
// @description  Checks if the script is loaded by Greasemonkey or not
// @author       @TinyGiant
// @grant        none
// ==/UserScript==

const isGM = 'undefined' === typeof GM_info.script.author;
console.log(`Is Greasemonkey? ${isGM}`);

检查什么是管理器 运行 是一种糟糕的方法,这将被证明是脆弱的和高维护性的。 聪明的做法是检查这个神秘的功能是否存在,或者是否按需要工作。

这与"browser sniffing"属于同一类型的问题,答案是相同的:Use feature detection instead.
例如:

if (typeof dicyFunc == "function") {
    //-- Use the function
    dicyFunc ();
}
else {
    console.error ("This userscript engine does not support dicyFunc.");
}

用户评论更新: 有时您可能 还需要一个 try...catch 块。例如:

try {
    REALLY_dicyFunc ();
}
catch (zError) {
    console.error ("REALLY_dicyFunc fail on this engine: ", zError);
}

需要具体的例子(Make an MCVE)才能了解更多


如果您坚持进行引擎检测,请参阅 this answer 一个几乎重复的问题。 本质上,您将使用 GM_info.scriptHandler 属性,可能由 GM_info.version 属性.

支持

为获得最佳效果,请求 Greasemonkey 支持 scriptHandler属性。 (Tampermonkey 和 ViolentMonkey 已经这样做了。) 有a recently closed pull request for this for Greasemonkey,所以也许会在下个版本?