2012-11-21 17 views
6

ho il seguente codice nel test.js che è gestito a destra prima </body>:accesso a variabili da Greasemonkey alla pagina e viceversa

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

ho il seguente codice nel test.user .js:

(function() { 

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

}()); 

'fornelli' ottiene avvisati quindi so pagina javascript funziona e ottiene document.title cambiamenti quindi so che lo script javascript funziona. Tuttavia, sulla pagina Web ottengo l'errore:

Error: ReferenceError: greasy is not defined Source File: /test.js

Come dalla pagina web faccio ad accedere alla variabile fissato dal Greasemonkey e come circa viceversa?

+1

Se si va in questo modo, funzionerà solo in firefox come script per gli utenti sandbox di Chrome. – apscience

risposta

25
  • script Greasemonkey operano in un ambito separato e possono anche operare in una sandbox, a seconda della @grant settings.

  • Inoltre, il codice di domanda isola greasy in un ambito funzione (come ha detto gladoscc).

  • Infine, per impostazione predefinita, test.js spareranno prima dello script Greasemonkey lo fa, in modo che non vedranno alcuna variabile set, comunque. Utilizzare @run-at document-start per risolverlo.


Quindi, data questa test.js, correre a destra prima di </body>:

window.targetPages_GlobalVar = 'stovetop'; 

console.log ("On target page, local global: ", targetPages_GlobalVar); 
console.log ("On target page, script global: ", gmScripts_GlobalVar); 

Poi il seguente funzionerà:

No sandbox:

// ==UserScript== 
// @name  _Greasemonkey and target page, variable interaction 
// @include  http://YOUR_SERVER.COM/YOUR_PATH/* 
// @include  http://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); 


Con sandbox, nessuna funzione ambito, unsafeWindow:
== > Importante aggiornamento:Greasemonkey changed unsafeWindow handling with version 2.0, the next sample script will not work with GM 2.0 or later. Le altre due soluzioni funzionano ancora.

// ==UserScript== 
// @name  _Greasemonkey and target page, variable interaction 
// @include  http://YOUR_SERVER.COM/YOUR_PATH/* 
// @include  http://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); 


Con sandbox, alcun margine di funzione, Script iniezione:

// ==UserScript== 
// @name  _Greasemonkey and target page, variable interaction 
// @include  http://YOUR_SERVER.COM/YOUR_PATH/* 
// @include  http://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); 
} 

Note:

  1. È possibile verificare questi script su this page (jsbin.com/esikut).
  2. Senza sandbox, unsafeWindow e window sono gli stessi.
  3. Tutti questi script produrre la stessa uscita sulla console:

    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 
    
  4. The Script codice iniezione lavoreranno in una varietà di browser oltre a Firefox. unsafeWindow attualmente funziona solo in Firefox + Greasemonkey (o Scriptish) o Chrome + Tampermonkey.

+0

Fantastico, grazie per l'ottima spiegazione! –

+0

bw http://wiki.greasespot.net/UnsafeWindow dice che è pericoloso usare la Finestra non sicura, quale sarebbe un'alternativa più sicura in questo caso? –

+1

L'alternativa "più sicura" sarebbe utilizzare il metodo '@grant none' ma sostituire' unsafeWindow' con 'window' (sebbene siano identici quando' @grant none' è in effetti), ** o ** da usare il metodo * Script Injection *. ... Tuttavia, il rischio di usare 'unsafeWindow' è enormemente esagerato - senza alcun vero exploit riportato. Finché non sei su un sito che si rivolge attivamente agli script GM, non ci dovrebbero essere rischi. –

1

La variabile greasy è definita nell'ambito della funzione anonima. Non è possibile accedere a greasy anche nel proprio userscript, a meno che non faccia parte della propria funzione. Esempio:

(function(){ 
    var foo = 5; 
    alert(foo); 
}(); 
alert(foo); //ERROR, because foo is undefined outside of the function. 

fare in questo modo:

var foo = 5; 
(function(){ 
    alert(foo); 
}(); 
alert(foo); 

Inoltre, perché stai mettendo tutto il codice in una funzione anonima e quindi eseguirlo?

+0

Ho appena usato uno script modello greasemonkey e aveva il codice di esempio nella funzione anonima. Supponevo che fosse necessario per gli script greasemonkey. Ho spostato la dichiarazione var al di fuori della funzione e non riesco ancora ad avvisare il valore della variabile dallo script test.js sulla pagina. –

+0

Potrebbe essere eseguito il mio script test.js prima di Greasemonkey? Se sì, come posso ritardarlo? –

Problemi correlati