Executing host script from an injected page

别等时光非礼了梦想. 提交于 2020-01-31 16:43:13

问题


I'm writing a Safari Extension that adds some functionality to a web page that I don't own. I would like for my injected JavaScript page to be able to fire some JavaScript functions the host page uses, but it doesn't work. On the Console I get the message ReferenceError: Can't find variable: function_name.

My script is specified to be an End Script, so the whole page should be loaded. The function is also called from an onclick() handler on the page, like so:

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

I can get a reference to that page element, but when I call element.onclick() I get another error: TypeError: 'undefined' is not a function (evaluating '$(this).up()').

Oddly, when I call the JavaScript function from an AppleScript (do JavaScript "function_name()" in page) it works fine. How can I trigger these functions?


回答1:


I can extend answer from canisbos. You can communicate with the inserted script with the PostMessage function.

injected script:

//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);

Test html page:

<html>
<script>
  function foo(text) {
    console.log(text);
  };
</script>
<body>
  <button id='button' onclick='foo("from page")'>test</button>
</body>
</html>



回答2:


It's not working because the extension's injected script is sandboxed; it can't see the page's global objects except for the DOM (and vice versa). A way around this security limitation is to have the injected script create a <script> element with the statements you want and insert it into the document. For example:

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

However, the inserted script will not have access to the injected script's objects either. So, for example, if you try to access the extension's safari object from the inserted script, you will get a reference error.



来源:https://stackoverflow.com/questions/8927887/executing-host-script-from-an-injected-page

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!