我在之前运行的test.js中有以下代码:

alert('stovetop');
alert(greasy);

我在test.user.js中有以下代码:
(function () {

    'use strict';
    var greasy = 'greasy variable';
    document.title = 'greasy title';

}());

'stovetop'收到警报,因此我知道页面javascript可以工作,而document.title得到更改,因此我知道脚本javascript可以工作。但是,在网页上我得到了错误:



如何从网页上访问Greasemonkey设置的变量,反之亦然?

最佳答案

  • Greasemonkey脚本在单独的范围内运行,并且还可以在沙箱中运行,具体取决于 @grant settings
  • 此外,问题代码将greasy隔离在函数范围内(如gladoscc所说)。
  • 最后,默认情况下, test.js 将在Greasemonkey脚本执行之前启动,因此无论如何它都不会看到任何设置变量。使用 @run-at document-start 解决该问题。

  • 因此,鉴于此 test.js ,请在</body>之前运行:
    window.targetPages_GlobalVar = 'stovetop';
    
    console.log ("On target page, local global: ", targetPages_GlobalVar);
    console.log ("On target page, script global: ", gmScripts_GlobalVar);
    

    然后,以下内容将起作用:

    无沙箱:
    // ==UserScript==
    // @name        _Greasemonkey and target page, variable interaction
    // @include     http://YOUR_SERVER.COM/YOUR_PATH/*
    // @include     http://output.jsbin.com/esikut/*
    // @run-at      document-start
    // @grant       none
    // ==/UserScript==
    
    //--- For @grant none, could also use window. instead of unsafeWindow.
    unsafeWindow.gmScripts_GlobalVar = 'greasy';
    
    console.log ("In GM script, local global: ", unsafeWindow.targetPages_GlobalVar);
    console.log ("In GM script, script global: ", gmScripts_GlobalVar);
    
    window.addEventListener ("DOMContentLoaded", function() {
        console.log ("In GM script, local global, after ready: ", unsafeWindow.targetPages_GlobalVar);
    }, false);
    

    使用沙箱,无功能范围,unsafeWindow:
    ==> 重要更新: Greasemonkey changed unsafeWindow handling with version 2.0, the next sample script will not work with GM 2.0 or later。其他两个解决方案仍然有效。
    // ==UserScript==
    // @name        _Greasemonkey and target page, variable interaction
    // @include     http://YOUR_SERVER.COM/YOUR_PATH/*
    // @include     http://output.jsbin.com/esikut/*
    // @run-at      document-start
    // @grant    GM_addStyle
    // ==/UserScript==
    /*- The @grant directive is needed to work around a design change
        introduced in GM 1.0.   It restores the sandbox.
    */
    
    unsafeWindow.gmScripts_GlobalVar = 'greasy';
    
    console.log ("In GM script, local global: ", unsafeWindow.targetPages_GlobalVar);
    console.log ("In GM script, script global: ", unsafeWindow.gmScripts_GlobalVar);
    
    window.addEventListener ("DOMContentLoaded", function() {
        console.log ("In GM script, local global, after ready: ", unsafeWindow.targetPages_GlobalVar);
    }, false);
    

    使用沙箱,无功能范围,脚本注入(inject):
    // ==UserScript==
    // @name        _Greasemonkey and target page, variable interaction
    // @include     http://YOUR_SERVER.COM/YOUR_PATH/*
    // @include     http://output.jsbin.com/esikut/*
    // @run-at      document-start
    // @grant       GM_addStyle
    // ==/UserScript==
    /*- The @grant directive is needed to work around a design change
        introduced in GM 1.0.   It restores the sandbox.
    */
    
    function GM_main () {
        window.gmScripts_GlobalVar = 'greasy';
    
        console.log ("In GM script, local global: ", window.targetPages_GlobalVar);
        console.log ("In GM script, script global: ", window.gmScripts_GlobalVar);
    
        window.addEventListener ("DOMContentLoaded", function() {
            console.log ("In GM script, local global, after ready: ", window.targetPages_GlobalVar);
        }, false);
    }
    
    addJS_Node (null, null, GM_main);
    
    function addJS_Node (text, s_URL, funcToRun, runOnLoad) {
        var D                                   = document;
        var scriptNode                          = D.createElement ('script');
        if (runOnLoad) {
            scriptNode.addEventListener ("load", runOnLoad, false);
        }
        scriptNode.type                         = "text/javascript";
        if (text)       scriptNode.textContent  = text;
        if (s_URL)      scriptNode.src          = s_URL;
        if (funcToRun)  scriptNode.textContent  = '(' + funcToRun.toString() + ')()';
    
        var targ = D.getElementsByTagName ('head')[0] || D.body || D.documentElement;
        targ.appendChild (scriptNode);
    }
    

    笔记:
  • 您可以针对this page (output.jsbin.com/esikut/1)测试这些脚本。
  • 如果没有沙箱,则unsafeWindowwindow相同。
  • 所有这些脚本在控制台上产生相同的输出:

    In GM script, local global: undefined
    In GM script, script global: greasy
    On target page, local global: stovetop
    On target page, script global: greasy
    In GM script, local global, after ready: stovetop
    
  • 脚本注入(inject)代码将在Firefox之外的各种浏览器中运行。 unsafeWindow当前仅在Firefox + Greasemonkey(或Scriptish)或Chrome + Tampermonkey中有效。
  • 关于javascript - 从Greasemonkey到Page的访问变量,反之亦然,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/13485122/

    10-11 23:32