"eval не является функцией" при использовании iframe и Greasemonkey/Scriptish
Можно ли как-нибудь заставить этот кусок кода работать внутри Greasemonkey/Scriptish, или мне нужно будет вставить его в саму веб-страницу?
body = document.getElementsByTagName("body")[0];
fakeConsole = 'window.top._console';
injected = document.getElementById("sandbox") ? true : false;
sandboxframe = injected ? document.getElementsById("sandbox") : document.createElement('iframe');
sandbox = null;
if (!injected) {
body.appendChild(sandboxframe);
sandboxframe.setAttribute('id', 'sandbox');
sandboxframe.setAttribute('style', "display:none")
}
var p = sandboxframe.contentWindow.eval('1 + 1');
console.log(p);
Этот код работает при использовании исходного кода:
<script type="text/javascript" src="test.js"></script>
Но не при использовании в скрипте Greasemonkey я заметил, что есть какой-то барьер безопасности, с которым я не совсем знаком, и попытался использовать unsafeWindow для обхода XPCNativeWrapper.
Пожалуйста, пролите немного света на это.
1 ответ
Несколько вещей:
- Код имеет ошибку;
getElementsById
это не функция. - Этот код работает в Greasemonkey 1.0 или более поздней версии, если
@grant none
Директива применяется. Подробнее об этом ниже. - Для скриптов, всех других браузеров и сценариев Greasemonkey, где
@grant none
это невозможно; вам придется "ввести" код. Подробнее об этом ниже. - Как говорит Джереми Дж. Старчер,
eval()
следует избегать как можно больше.eval()
значительно усложняет работу, обслуживание, отладку и безопасность.
Для Greasemonkey 1.0 и более поздних версий:
В некоторых случаях Greasemonkey больше не использует XPCNativeWrapper
, Смотрите документ для @grant
директива
Так что это означает, что (1) Если ваш скрипт не использует GM_
функции и (2) скрипт указывает @grant none
, тогда ваш код будет работать как есть (за исключением getElementsById
опечатка).
Обратите внимание, что никакой другой скрипт-движок не делает этого. (По чертовски веским причинам. Новое поведение Greasemonkey относительно @grant
и песочница в лучшем случае противоречива.)
Если вы хотите использовать GM_
функции, то вы должны ввести код iframe. Смотрите следующий раздел.
Для скриптов, привилегированных Greasemonkey, Chrome и т.д.:
Scriptish, Sandboxed Greasemonkey, Chrome и т. Д. Не всегда хорошо обрабатывают фреймы из соответствующих песочниц. (См. Эти вопросы, например.)
Единственный надежный способ запустить этот вид кода из GM/userscript - это внедрить его. Вот так:
function gmMain () {
body = document.getElementsByTagName("body")[0];
fakeConsole = 'window.top._console';
injected = document.getElementById("sandbox") ? true : false;
sandboxframe = injected ? document.getElementById("sandbox") : document.createElement('iframe');
sandbox = null;
if (!injected) {
body.appendChild(sandboxframe);
sandboxframe.setAttribute('id', 'sandbox');
sandboxframe.setAttribute('style', "display:none")
}
var p = sandboxframe.contentWindow.eval('1 + 1');
console.log(p);
}
addJS_Node (null, null, gmMain);
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);
}