如何从用户脚本访问iframe的javascript?

Ski*_*927 5 javascript iframe greasemonkey google-chrome tampermonkey

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

<body>
content up here

<iframe id="main" src="foo.dat"></iframe>
</body>
Run Code Online (Sandbox Code Playgroud)

iframe是同源的.

我需要访问一个函数iframe#main.我以为我可以unsafeWindow用来获得它,但我一直没有得到或undefined返回.

我尝试了很多东西:

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

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

我已经尝试了许多其他我不记得的事情,但是我已经用尽了所有的想法,觉得我输入的垃圾比任何重要的垃圾都要多.
我无法弄清楚如何使用unsafeWindowiFrame.

Bro*_*ams 10

  1. unsafeWindow 与Chrome,Tampermonkey或Firefox上的框架/ iframe不相称.
  2. 尝试使用jQuery访问全局(到框架)JS,就像这样,将无法工作.
  3. userscripts将在满足I帧运行@include,@exclude和/或@match要求.

因此,您需要考虑多个脚本运行,然后您有两种基本方法,具体取决于您要完成的操作.您可以:

(A)将脚本定制到特定的框架,如本答案所示.

或者(B)注入你的JS并使用特殊frames对象来获取你想要的特定功能.

以下脚本演示了两者.将其安装在Tampermonkey 1(或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");
Run Code Online (Sandbox Code Playgroud)



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

Tampermonkey started
Script start...
calling functionOfInterest ()...
Userscript is in the MAIN page.
Script end
Tampermonkey started
Script start...
calling functionOfInterest ()...
Userscript is in the FRAMED page.
The frame's ID is: iframe2
Script end

1如果删除unsafeWindow行,它也可以作为直接的Chrome用户脚本使用.