6

被欺骗的候选人是以前的 GM 版本。问题可能出在用户脚本可以运行的不同范围内,如此处所述。但是,如此处所述,Greasemonkey 4.0 目前没有记录此功能

我有这个 Greasemonkey 演示脚本:

// ==UserScript==
// @name         GM_getValue, GM_setValue don't work demo
// @version      0.2
// @author       You
// @include      /^https:\/\/stackoverflow.com/$/
// @grant        GM_getValue
// @grant        GM_setValue
// @run-at       document-end
// ==/UserScript==

console.log('script started');
var id = GM_getValue('testName', 0);
console.log('got ' + id);
id++;
GM_setValue('testName', id);

用https://stackoverflow.com/调用它,很明显它被调用了。

但是,我在控制台上收到此错误:

Script error:  
ReferenceError: GM_getValue is not defined
Stack trace:
userScript@user-script:demosrv/GM_getValue%2C%20GM_setValue%20don%27t%20work%20demo:372:5
scopeWrapper@user-script:demosrv/GM_getValue%2C%20GM_setValue%20don%27t%20work%20demo:381:9
@user-script:demosrv/GM_getValue%2C%20GM_setValue%20don%27t%20work%20demo:361:17

我已经挖掘了很多文档,但似乎GM_{get,set}Value根本不想存在。

为什么会这样?如何让它工作?

我正在使用火狐。

4

1 回答 1

12

GM_getValueGM_setValue现在在 GreaseMonkey 中已过时。正确的方法是GM.setValueGM.getValue

GreaseMonkey 文档经常使用旧的 API 调用名称,这是其中的一个连续错误。可能它没有正确更新。

正如这里的文档所说,GM 函数可以在不同的范围内运行。不幸的是,直到现在我还没有找到任何信息,哪些范围存在以及我们如何在它们之间切换。

网上很多地方的旧参考资料GM_getValue都已经过时了。

重要的事情:

  • WhileGM_getValue是具有返回值的函数,GM.getValue并且GM.setValuereturn Promises。
  • 通过调用,您几乎可以像在旧的、漂亮的版本中使用它们一样使用它们await

远程链接上的此示例有效:

// ==UserScript==
// @name        Greasemonkey set-and-get Example
// @description Stores and logs a counter of executions.
// @grant       GM.setValue
// @grant       GM.getValue
// ==/UserScript==

(async () => {
  let count_before = await GM.getValue('count', 0);

  // Note awaiting the set -- required so the next get sees this set.
  await GM.setValue('count', count_before + 1);

  // Get the value again, just to demonstrate order-of-operations.
  let count_after = await GM.getValue('count');

  console.log('Greasemonkey set-and-get Example has run', count_after, 'times');
})();

但是,仍然没有关于范围以及我们如何与它们交互的更清晰的文档。

看来,至少有两个范围:

  • 在其中之一中,您可以操作 DOM,但无权访问GM.*API。
  • 在另一种情况下,您可以访问GM.*API(因此,您可以制作脚本本地持久存储),但无权访问 DOM。
  • 在作用域之间,我们可以通过异步调用进行通信。
  • 为什么这个麻烦会增加安全性,可能甚至 GM 开发人员都不能说。

因此,为 4.0 开发新的 GreaseMonkey 脚本的方法是从他们的示例脚本开始,然后遵循增量试验和错误路径。


扩展:我发现的另一个麻烦:await脚本中的存在似乎使greasemonkey 忽略整个脚本等。在示例中,它似乎没有发生,但在更复杂的脚本中,它确实发生了。我没有对它进行过深入的调试——我只是忽略await并以旧方式(GM.getValue("myValue").then(function(myValue) { ... });)使用 Promises。它使代码更蹩脚,但也是如此。

于 2017-11-24T15:42:08.000 回答