如何访问iframe's来自用户脚本的javascript

How do I access an iframe's javascript from a userscript?

本文关键字:用户 脚本 javascript 何访问 访问 iframe      更新时间:2024-01-26

我正试图使用Chrome用户脚本或Tampermonkey脚本来修改具有以下结构的页面:

<body>
content up here
<iframe id="main" src="foo.dat"></iframe>
</body>

iframe是同源的。

我需要访问iframe#main中的一个函数。我认为我可以使用unsafeWindow来获得它,但我一直一无所获或返回了undefined

我尝试了很多东西:

  • 尝试在iframe中创建一个新的脚本元素,但即使使用$('frame#main').contents().append(script)$('frame#main').contents()[0].createElement('script') ,它也会附着到父元素

  • window.frames["#main"].contentWindow返回undefined。

我试过很多其他我现在记不起的事情,但我已经用尽了所有的想法,觉得我打字比任何重要的东西都要垃圾
我不知道怎么玩iFrame的unsafeWindow

  1. unsafeWindow在Chrome、Tampermonkey或Firefox上使用框架/iframe时效果不佳
  2. 尝试用jQuery访问全局(到框架)JS,就像那样,是行不通的
  3. 用户脚本将在满足@include@exclude和/或@match要求的iframe上运行

因此,您需要考虑多个脚本运行,然后您有两种基本方法,这取决于您试图实现的目标。您可以:

(A) 根据特定的框架定制脚本,如本答案所示。

或者(B)注入JS并使用特殊的frames对象来获取您想要的特定函数。

下面的脚本演示了两者。将其安装在Tampermonkey1(或Firefox Greasemonkey)中,然后访问jsBin上的测试页面。

// ==UserScript==
// @name        _Calling iframe functions
// @namespace   _pc
// @include     http://jsbin.com/ugoruz/*
// @include     http://jsbin.com/okequw/*
// ==/UserScript==
console.log ("Script start...");
/*--- This next function call will work in Firefox or Tampermonkey ONLY,
    not pure Chrome userscript.
*/
console.log ("calling functionOfInterest ()...");
unsafeWindow.functionOfInterest ();

if (window.top === window.self) {
    //--- Code to run when page is the main site...
    console.log ("Userscript is in the MAIN page.");
    //--- The frames object does not play nice with unsafeWindow.
    /*--- These next three work in Firefox, but not Tampermonkey, nor pure Chrome.
    console.log ("1", frames[1].variableOfInterest);                // undefined
    console.log ("2", unsafeWindow.frames[1].variableOfInterest);   // undefined
    console.log ("3", frames[1].unsafeWindow);                      // undefined
    */
    /*--- This next would cause a silent crash, all browsers...
    console.log ("4", unsafeWindow.frames[1].unsafeWindow.variableOfInterest);
    */
    //--- To get at iFramed JS, we must inject our JS.
    withPages_jQuery (demoAccessToFramedJS);
}
else {
    //--- Code to run when page is in an iframe...
    console.log ("Userscript is in the FRAMED page.");
    console.log ("The frame's ID is:", window.self.frameElement.id);
}

function demoAccessToFramedJS ($) {
    $("body").prepend (
          '<button id="gmMain">Run JS on main window</button>'
        + '<button id="gmFrame">Run JS on iframe</button>'
    );
    $("#gmMain, #gmFrame").click ( function () {
        if (this.id === "gmMain") {
            functionOfInterest ();
        }
        else {
            frames[1].functionOfInterest ();
        }
        console.log (this.id + "was clicked.");
    } );
}
function withPages_jQuery (NAMED_FunctionToRun) {
    //--- Use named functions for clarity and debugging...
    var funcText        = NAMED_FunctionToRun.toString ();
    var funcName        = funcText.replace (/^function's+('w+)'s*'((.|'n|'r)+$/, "$1");
    var script          = document.createElement ("script");
    script.textContent  = funcText + "'n'n";
    script.textContent += 'jQuery(document).ready(function() {'+funcName+'(jQuery);});';
    document.body.appendChild (script);
};
console.log ("Script end");



您将看到该脚本从主页面和iframe运行一个函数。控制台输出(Tampermonkey)将为:

Tampermonkey开始脚本启动。。。正在调用functionOfInterest()。。。Userscript在MAIN页面中。脚本结束Tampermonkey开始脚本启动。。。正在调用functionOfInterest()。。。Userscript位于FRAMED页面中。框架的ID为:iframe2脚本结束

1如果删除unsafeWindow行,它也将作为一个直接的Chrome用户脚本工作。