【问题标题】:Call to a complex page function works in Tampermonkey but not Greasemonkey?调用复杂页面函数在 Tampermonkey 中有效,但在 Greasemonkey 中无效?
【发布时间】:2016-12-25 12:39:50
【问题描述】:

我正在尝试为 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 的同时实现这一点?

【问题讨论】:

    标签: firefox greasemonkey tampermonkey


    【解决方案1】:

    如果您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?。这种情况属于“复杂功能:这并不总是可能”的情况。

    所以,你需要注入调用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_ 功能 - 有一天需要对此进行调查。 .. :)

    【讨论】:

      猜你喜欢
      • 2016-01-02
      • 1970-01-01
      • 1970-01-01
      • 2023-01-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-12-26
      • 1970-01-01
      相关资源
      最近更新 更多