UserScripts & Greasemonkey: вызов функций JavaScript веб-сайта - PullRequest
33 голосов
/ 15 февраля 2011

Я создаю расширение UserScript для Firefox & Chrome и пытаюсь использовать часть кода в JavaScript веб-сайта, например:

function: myFunction(){
    return  Grooveshark.playNextSong();
}

Проблема заключается в том, что когда я тестирую этот код,Grooveshark является пустой ссылкой.

Я знаю, что есть другие люди, которые сделали это:

см. BetterGrooveshark

Но я не знаюзнаете, почему мое простое расширение не может вызывать JavaScript-функции Grooveshark.

Нужно ли "добавлять" мой скрипт в документ, чтобы это работало ?: document.document.body.appendChild(script);

Разве нет?t Greasemonkey внедрить мои расширения JavaScript уже?Может кто-нибудь уточнить это для меня, пожалуйста.

Спасибо.

Ответы [ 2 ]

72 голосов
/ 15 февраля 2011

Фон

Разве Greasemonkey не вводит мои расширения JavaScript уже? Может кто-нибудь уточнить это для меня, пожалуйста.

Greasemonkey выполняет ваши сценарии в песочнице , которая является ограниченной средой без прямого доступа к JavaScript на странице. Более ранние версии Greasemonkey вводили скрипты прямо на страницу, но это приводило к серьезным уязвимостям безопасности. В старой модели сценарии выполнялись с повышенными правами браузера Chrome, что позволяло удаленным страницам получать доступ к встроенным функциям Greasemonkey с использованием некоторого умного JavaScript . Это было плохо:

Сценарии Greasemonkey содержали свой собственный объект GM_xmlhttprequest, который, в отличие от обычного объекта xmlttprequest, мог обращаться к любым локальным файлам на своем компьютере или делать произвольные запросы к произвольным сайтам без учета той же политики происхождения, которая обычно применяется к xmlhttprequest. (источник)

Когда вы получаете доступ к объекту window из сценария Greasemonkey сегодня, вы получаете объект-оболочку , который косвенно ссылается на фактические свойства window. Этот объект-оболочку можно безопасно изменять, но имеет важные ограничения . Доступ к реальному объекту окна обеспечивается unsafeWindow (сокращение для window.wrappedJSObject). Использование unsafeWindow заново открывает все исходные проблемы безопасности Greasemonkey и недоступно в Chrome. Этого следует избегать везде, где это возможно.

Хорошая новость: есть по крайней мере два способа безопасной работы с новой моделью безопасности Greasemonkey.

Внедрение скрипта

Теперь, когда сценарии Greasemonkey могут безопасно обращаться к DOM, просто вставить тег <script> в <head> целевого документа. Создайте такую ​​функцию:

function exec(fn) {
    var script = document.createElement('script');
    script.setAttribute("type", "application/javascript");
    script.textContent = '(' + fn + ')();';
    document.body.appendChild(script); // run the script
    document.body.removeChild(script); // clean up
}

Прост в использовании:

exec(function() {
    return Grooveshark.playNextSong();
});

Местоположение Hack

Внедрение скрипта может быть излишним в некоторых случаях, особенно когда все, что вам нужно, это изменить значение переменной на странице или выполнить одну функцию. Location Hack использует javascript: URL для доступа к коду в содержании документа. Это похоже на запуск букмарклета из скрипта Greasemonkey.

location.assign("javascript:Grooveshark.playNextSong();void(0)");

Бонусный скрипт

Вот полный скрипт Greasemonkey, который демонстрирует примеры выше. Вы можете запустить его на этой странице.

// ==UserScript==
// @name           Content Function Test
// @namespace      lwburk
// @include        /4377789/userscripts-greasemonkey-vyzov-funktsii-javascript-veb-saita
// ==/UserScript==

function exec(fn) {
    var script = document.createElement('script');
    script.setAttribute("type", "application/javascript");
    script.textContent = '(' + fn + ')();';
    document.body.appendChild(script); // run the script
    document.body.removeChild(script); // clean up
}

window.addEventListener("load", function() {
    // script injection
    exec(function() {
        // alerts true if you're registered with Stack Overflow
        alert('registered? ' + isRegistered);
    });
    // location hack
    location.assign("javascript:alert('registered? ' + isRegistered);void(0)");
}, false);
11 голосов
/ 15 февраля 2011

Функции и переменные, объявленные в ваших скриптах GreaseMonkey (и пользовательских скриптах Chrome), по понятным причинам хранятся отдельно от тех, которые объявлены веб-страницей.Для сценариев GM в Firefox вы можете получить доступ к глобальным переменным через unsafeWindow.

. Лучший подход для обеспечения безопасности и совместимости состоит в том, чтобы внедрить ваши функции в страницу с помощью элемента script.Я использую следующий фрагмент в моих пользовательских скриптах:

function addFunction(func, exec) {
  var script = document.createElement("script");
  script.textContent = "-" + func + (exec ? "()" : "");
  document.body.appendChild(script);
}

"-" здесь гарантирует, что функция анализируется как выражение, так что exec может использоваться для немедленного выполнения при добавлении.Вы вызываете функцию так:

function myFunction () {
    return Grooveshark.playNextSong();
}

// Inject the function and execute it:
addFunction(myFunction, true);
...