Доступ к переменным из Greasemonkey на страницу и наоборот
У меня есть следующий код в test.js, который запускается прямо перед body>:
alert('stovetop');
alert(greasy);
У меня есть следующий код в test.user.js:
(function () {
'use strict';
var greasy = 'greasy variable';
document.title = 'greasy title';
}());
"stovetop" получает предупреждение, так что я знаю, что страница работает на JavaScript, и document.title
получает изменения, поэтому я знаю, что скрипт javascript работает. Однако на веб-странице я получаю сообщение об ошибке:
Ошибка: ReferenceError: жирный не определен Исходный файл: /test.js
Как с веб-страницы получить доступ к переменной, установленной Greasemonkey, и как насчет наоборот?
3 ответа
Сценарии Greasemonkey работают в отдельной области и могут также работать в песочнице, в зависимости от
@grant
НастройкиКроме того, код вопроса изолирует
greasy
в объеме функции (как сказал гладоск).Наконец, по умолчанию 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://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 изменил обработку unsafeWindow с версией 2.0, следующий пример скрипта не будет работать с GM 2.0 или новее. Два других решения все еще работают.
// ==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);
С песочницей, без области действия, Script Injection:
// ==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);
}
Заметки:
- Вы можете проверить эти сценарии на этой странице (jsbin.com/esikut).
- Без песочницы,
unsafeWindow
а такжеwindow
подобные. Все эти скрипты выдают одинаковый вывод на консоль:
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
Код Script Injection будет работать во многих браузерах, кроме Firefox.
unsafeWindow
в настоящее время работает только в Firefox+Greasemonkey(или Scriptish) или Chrome+Tampermonkey.
Вы также можете использовать localStorage:
localStorage.setItem("numberOfThings", "42");
localStorage.getItem("numberOfThings");
Ваша переменная greasy
определяется в области действия анонимной функции. Вы не можете получить доступ greasy
даже в вашем пользовательском сценарии, если это не часть вашей функции. Пример:
(function(){
var foo = 5;
alert(foo);
}();
alert(foo); //ERROR, because foo is undefined outside of the function.
Сделай это так:
var foo = 5;
(function(){
alert(foo);
}();
alert(foo);
Кроме того, почему вы помещаете весь свой код в анонимную функцию, а затем выполняете ее?