2012-11-21 13 views
6

Mam następujący kod w test.js który jest prowadzony tuż przed </body>:Dostęp do zmiennych z Greasemonkey do strony i odwrotnie

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

Mam następujący kod w test.user js:

(function() { 

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

}()); 

„stovetop” zostanie powiadomiony więc wiem stronę javascript działa i document.title wystąpią zmiany, więc wiem, że skrypt javascript działa. Jednakże, na stronie pojawia się błąd:

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

Jak od strony mogę uzyskać dostęp do zmiennej ustawiony przez Greasemonkey i jak o odwrotnie?

+1

Jeśli pójdziesz tą drogą, działa ona tylko w Firefoksie jako użytkownicy Chromebooków userscripts. – apscience

Odpowiedz

25
  • Greasemonkey skrypty działają w odrębnym zakresie i może także działać w piaskownicy, w zależności od @grant settings.

  • Ponadto kod zapytania izoluje greasy w zakresie funkcji (jak powiedział gladoscc).

  • Wreszcie domyślnie test.js zadziała zanim Greasemonkey skrypt robi, więc nie będzie widać żadnych ustawić zmienne, tak. Użyj adresu @run-at document-start, aby rozwiązać ten problem.


więc, biorąc pod uwagę to test.js, prowadzony tuż przed </body>:

window.targetPages_GlobalVar = 'stovetop'; 

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

Następnie dodaje zadziała:

No piaskownicy:

// ==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); 


Z piaskownicy, bez zakres funkcji, unsafeWindow:
== > Ważna aktualizacja:Greasemonkey changed unsafeWindow handling with version 2.0, the next sample script will not work with GM 2.0 or later. Pozostałe dwa rozwiązania nadal działają.

// ==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); 


Z piaskownicy, bez zakres funkcji, Script wtrysku:

// ==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); 
} 

Uwagi:

  1. można przetestować te skrypt przeciwko this page (jsbin.com/esikut).
  2. Bez piaskownicy, unsafeWindow i window są takie same.
  3. Wszystkie te skrypty wytwarzają taką samą moc na konsoli:

    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. Script kod wtryskowa będzie działać w różnych przeglądarkach oprócz Firefoksa. unsafeWindow obecnie działa tylko w Firefox + Greasemonkey (lub Scriptish) lub Chrome + Tampermonkey.

+0

Wspaniale, dziękuję za wspaniałe wyjaśnienie! –

+0

btw http://wiki.greasespot.net/UnsafeWindow mówi, że korzystanie z niebezpiecznego systemu Windows jest niebezpieczne, jaka byłaby w tym przypadku bezpieczniejsza alternatywa? –

+1

"Bezpieczniejszą" alternatywą byłoby użycie metody '@grant none', ale zastąpienie' unsafeWindow' przez 'window' (chociaż są one identyczne, gdy' @grant none' jest w użyciu), ** lub ** w użyciu metoda * Injection skryptu *. ... Jednak ryzyko użycia "unsafeWindow" jest znacznie przekroczone - nie zgłoszono prawdziwych exploitów. Dopóki nie jesteś na stronie, która aktywnie atakuje skrypty GM, nie powinno być żadnego ryzyka. –

1

Twoja zmienna greasy jest zdefiniowana w zakresie funkcji anonimowej. Nie możesz uzyskać dostępu do greasy nawet w swoim userpadzie, chyba że jest to część funkcji. Przykład:

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

zrobić to w ten sposób:

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

także, dlaczego umieszczenie wszystkich kod w anonimowej funkcji, a następnie je wykonuje?

+0

Po prostu użyłem skryptu szablonu greasemonkey i miał przykładowy kod w anonimowej funkcji. Przyjąłem, że jest to wymagane w skryptach z grubymi łapami. Przenieśliłem deklarację var poza funkcją i nadal nie mogę ostrzec wartości zmiennej ze skryptu test.js na stronie. –

+0

Czy to możliwe, że mój skrypt test.js jest uruchamiany przed Greasemonkey? Jeśli tak, to jak mogę to opóźnić? –

Powiązane problemy