Javascript 从注入的页面执行主机脚本

Javascript 从注入的页面执行主机脚本,javascript,automation,obfuscation,safari-extension,Javascript,Automation,Obfuscation,Safari Extension,我正在编写一个Safari扩展,它为我不拥有的网页添加了一些功能。我希望我的注入JavaScript页面能够启动宿主页面使用的一些JavaScript函数,但它不起作用。在控制台上,我收到消息ReferenceError:找不到变量:function\u name 我的脚本被指定为结束脚本,因此应该加载整个页面。该函数也从页面上的onclick()处理程序调用,如下所示: onclick="function_name($(this).up());" 我可以获取对该页面元素的引用,但是当我调用元

我正在编写一个Safari扩展,它为我不拥有的网页添加了一些功能。我希望我的注入JavaScript页面能够启动宿主页面使用的一些JavaScript函数,但它不起作用。在控制台上,我收到消息
ReferenceError:找不到变量:function\u name

我的脚本被指定为结束脚本,因此应该加载整个页面。该函数也从页面上的
onclick()
处理程序调用,如下所示:

onclick="function_name($(this).up());"
我可以获取对该页面元素的引用,但是当我调用
元素.onclick()
时,我得到另一个错误:
TypeError:“undefined”不是函数(计算“$(this).up()”)


奇怪的是,当我从AppleScript调用JavaScript函数时(
dojavascript“function_name()”,在第
页),它工作得很好。如何触发这些函数?

它不起作用,因为扩展的注入脚本是沙盒;除了DOM之外,它看不到页面的全局对象(反之亦然)。绕过此安全限制的一种方法是让注入的脚本创建一个包含所需语句的
元素,并将其插入文档中。例如:

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

但是,插入的脚本也不能访问注入脚本的对象。因此,例如,如果您尝试从插入的脚本访问扩展的
safari
对象,您将得到一个引用错误。

我可以从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>

函数foo(文本){
console.log(文本);
};
测试

我是否有办法与插入的脚本通信?这是有用的信息,可以解释正在发生的事情,但我真的希望有一些解决方法。您可以使用DOM在注入的脚本(扩展)和插入的脚本之间进行某种通信。如果要将值从插入的脚本传递到插入的脚本,或者反之亦然,第一个脚本可以使用element.setAttribute()在文档中的元素上设置属性,稍后第二个脚本可以使用element.getAttribute()读取该属性。例如,您可以使用:document.documentElement.setAttribute('my_attr','999'),然后检索值:document.documentElement.getAttribute('my_attr'),但它必须每隔一段时间进行轮询?根据您的目标,这是一种方法。可能还有其他的。