调用复杂的页面函数在Tampermonkey中工作但不能在Greasemonkey中工作吗?

时间:2016-08-18 14:19:27

标签: firefox greasemonkey tampermonkey

我试图打开XenForo论坛的叠加对话框,重用现有的库:

// ==UserScript==
// @name         FooBar
// @match        https://xenforo.com/community/
// @grant        GM_getValue
// ==/UserScript==

(function() {
'use strict';

unsafeWindow.XenForo.createOverlay(null, $(`
<div class="xenOverlay">
    <form id="efd_form">
        <div class="section">
            <h2 class="heading h1">Greasemonkey test</h2>
            <h3 class="primaryContent">${GM_getValue('lorem', 'Lorem ipsum dolor sit amet …')}</h3>
        </div>
    </form>
</div>
`), { noCache: true }).load();
})();

使用Tampermonkey(Firefox / Chromium)访问https://xenforo.com/community/时,此脚本将打开简单对话框。
但是当你尝试使用Greasemonkey(Firefox)时没有任何反应。有没有办法在访问GM_getValue时实现这一目标?

1 个答案:

答案 0 :(得分:2)

如果您check the Browser Console of Firefox,您会看到如下错误消息:

  

$未定义 ... FooBar.user.js

这是因为使用@grant以外的none打开了Greasemonkey中的沙箱(以及Tampermonkey-ish)。这意味着脚本无法直接查看页面的javascript,因此jQuery未定义为脚本 ***

在您的代码中,您无法使用unsafeWindow技术来调用XenForo.createOverlay(),因为该函数需要在页面范围内定义/有效的jQuery对象(并且出于更复杂的原因)。登记/> 请参阅How to access `window` (Target page) objects when @grant values are set?。这种情况属于&#34;复杂功能:这并不总是可能的&#34;情况下。

因此,您需要注入调用XenForo.createOverlay()的代码。
但是,有一个障碍。由于GM_getValue()无法在页面范围内使用,因此您需要单独注入GM_getValue来电的结果。

此脚本说明了该过程并适用于两种浏览器:

// ==UserScript==
// @name     FooBar
// @match    https://xenforo.com/community/
// @grant    GM_getValue
// ==/UserScript==

unsafeWindow.GM_simplevar = GM_getValue ('lorem', 'Hello world!');

function GM_usePagesOverlay ($) {
    XenForo.createOverlay (null, $(`
    <div class="xenOverlay">
        <form id="efd_form">
            <div class="section">
                <h2 class="heading h1">Greasemonkey test</h2>
                <h3 class="primaryContent">${GM_simplevar}</h3>
            </div>
        </form>
    </div>
    `), { noCache: true }).load ();
}

withPages_jQuery (GM_usePagesOverlay);

function withPages_jQuery (NAMED_FunctionToRun) {
    //--- Use named functions for clarity and debugging...
    var funcText        = NAMED_FunctionToRun.toString ();
    var funcName        = funcText.replace (/^function\s+(\w+)\s*\((.|\n|\r)+$/, "$1");
    var script          = document.createElement ("script");
    script.textContent  = funcText + "\n\n";
    script.textContent += 'jQuery(document).ready(function() {'+funcName+'(jQuery);});';
    document.body.appendChild (script);
}


对于更复杂的数据交换,在页面范围和用户范围之间,您可能需要use messaging

*** Tampermonkey的行为违反了沙盒范例,可能成为一个安全漏洞,允许不良网页访问特权GM_功能 - 需要调查这一天...... :)。