Выполнение хост-скрипта со вставленной страницы - PullRequest
4 голосов
/ 19 января 2012

Я пишу расширение Safari, которое добавляет некоторые функции к веб-странице, которой я не владею. Я хотел бы, чтобы моя вставленная страница JavaScript могла запускать некоторые функции JavaScript, которые использует хост-страница, но это не работает. На консоли я получаю сообщение ReferenceError: Can't find variable: function_name.

Мой сценарий указан как конечный сценарий, поэтому должна быть загружена вся страница. Функция также вызывается из обработчика onclick() на странице, например:

onclick="function_name($(this).up());"

Я могу получить ссылку на этот элемент страницы, но когда я звоню element.onclick(), я получаю еще одну ошибку: TypeError: 'undefined' is not a function (evaluating '$(this).up()').

Как ни странно, когда я вызываю функцию JavaScript из AppleScript (do JavaScript "function_name()" in page), она работает нормально. Как я могу вызвать эти функции?

Ответы [ 2 ]

2 голосов
/ 10 февраля 2012

Я могу расширить ответ от canisbos.Вы можете связываться со вставленным скриптом с помощью функции PostMessage.

внедренный скрипт:

//insert script to page
var myScriptElement = document.createElement('script'); 
myScriptElement.innerHTML =
  'window.addEventListener("message", function(e) {' +
  '  if (e.data.msg == "do") {' +
  '    foo(e.data.info);' +
  '    postMessage({msg: "done", info: "answer"}, "*");' +
  '  };' +
  '}, false);'
document.querySelector('head').appendChild(myScriptElement);

//add answers listener
window.addEventListener('message', function(e) {
  if (e.data.msg == 'done') {
    console.log(e.data.info);
  };
}, false);

//add the testing function on the body click
document.addEventListener('click', function (e) {
  //call inserted script
  postMessage({msg: 'do', info: 'from inject'}, '*');
}, false);

Проверка html-страницы:

<html>
<script>
  function foo(text) {
    console.log(text);
  };
</script>
<body>
  <button id='button' onclick='foo("from page")'>test</button>
</body>
</html>
2 голосов
/ 19 января 2012

Это не работает, потому что внедренный скрипт расширения находится в песочнице; он не может видеть глобальные объекты страницы, кроме DOM (и наоборот). Чтобы обойти это ограничение безопасности, нужно, чтобы внедренный сценарий создал элемент <script> с необходимыми инструкциями и вставил его в документ. Например:

var myScriptElement = document.createElement('script');
myScriptElement.innerHTML = 'alert("Page is using jQuery " + $.fn.jquery)';
document.querySelector('head').appendChild(myScriptElement);

Однако вставленный скрипт также не будет иметь доступа к объектам внедренного скрипта. Так, например, если вы попытаетесь получить доступ к объекту расширения safari из вставленного скрипта, вы получите ошибку ссылки.

...