jQuery/JavaScript:访问iframe的内容

rz.*_*rz. 770 javascript iframe jquery same-origin-policy

我想使用jQuery操纵iframe中的HTML.

我以为我可以通过将jQuery函数的上下文设置为iframe的文档来实现这一点,例如:

$(function(){ //document ready
    $('some selector', frames['nameOfMyIframe'].document).doStuff()
});
Run Code Online (Sandbox Code Playgroud)

然而,这似乎不起作用.一些检查显示我的变量frames['nameOfMyIframe']undefined除非我等待一段时间加载iframe.但是,当iframe加载时,变量不可访问(我得到permission denied-type错误).

有没有人知道这方面的解决方法?

Yas*_*ari 971

如果<iframe>来自同一个域,则可以轻松访问这些元素

$("#iFrame").contents().find("#someDiv").removeClass("hidden");
Run Code Online (Sandbox Code Playgroud)

参考

  • 了解相同的原产地政策是很好的,但这是OP想要的答案.为什么另一个答案被选为正确答案? (151认同)
  • @JasonSwett,我的猜测是OP的问题确实是"同源策略",在这种情况下,这个答案对他来说不是解决方案. (7认同)
  • @fizzbuzz然后你得到IFrame的方式与使用jQuery获得任何其他无id内容的方式相同:你选择适当的<IFrame>标签和CSS,使用类名和属性值在必要时缩小范围. (3认同)
  • 您必须使用代理来获取原始HTML.例如,http://www.johnchapman.name/aspnet-proxy-page-cross-domain-requests-from-ajax-and-javascript/ (2认同)
  • iframe没有名为*contents*的方法. (2认同)
  • 对于任何想知道为什么这不是接受的答案的人 - 请注意日期.这是在提出问题一年之后; 如果OP会改变已接受的答案会很好,但5年以上不太可能.如果它困扰任何人,可能是Meta的问题; 我找到了我需要和投票的东西. (2认同)

Onu*_*bin 372

我认为你所做的事情遵循相同的原产地政策.这应该是您获得权限被拒绝类型错误的原因.

  • @ Tracker1:您能否为实现此代理解决方案建议任何框架/ api /设计模式.任何链接到示例或教程等?我试图搜索但找不到任何东西. (10认同)
  • @Pacerier最好的办法是代理您网站上iframe的内容,如果可以... (6认同)
  • 为了记录,我只是设置了类似的东西:如果你不希望结果非常慢,只需设置你的web服务器直接将资产请求(CSS/JS /图像)重新路由到原始网站,这样你的代理仅管理HTML请求.我正在浏览localhost下的一个远程站点,它绝对透明:) (4认同)
  • 在这种情况下,他表示使用为您的域名页面提供服务的http服务器作为代理 - 请求来自第三方站点的内容并将其在http响应中转发给客户端.正如您可能猜到的那样,它会迅速影响您站点的响应能力,因为之前的并行请求与您的服务器串行执行,这是一个潜在的瓶颈. (3认同)

小智 80

$(document).ready(function(){
    $('#frameID').load(function(){
        $('#frameID').contents().find('body').html('Hey, i`ve changed content of <body>! Yay!!!');
    });
});
Run Code Online (Sandbox Code Playgroud)

  • 我需要获取 i 帧内容而不是设置正文..... 当我执行上述操作时,它不起作用总是返回空正文 (5认同)
  • @DarkoZ嗯,实际上这个答案是第一个,所以如果有的话,另一个答案是副本 (3认同)

小智 41

如果iframe src来自另一个域,您仍然可以执行此操作.您需要将外部页面读入PHP并从您的域中回显它.像这样:

iframe_page.php

<?php
    $URL = "http://external.com";

    $domain = file_get_contents($URL);

    echo $domain;
?>
Run Code Online (Sandbox Code Playgroud)

然后这样的事情:

display_page.html

<html>
<head>
  <title>Test</title>
 </head>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.1/jquery.min.js"></script>

<script>

$(document).ready(function(){   
    cleanit = setInterval ( "cleaning()", 500 );
});

function cleaning(){
    if($('#frametest').contents().find('.selector').html() == "somthing"){
        clearInterval(cleanit);
        $('#selector').contents().find('.Link').html('ideate tech');
    }
}

</script>

<body>
<iframe name="frametest" id="frametest" src="http://yourdomain.com/iframe_page.php" ></iframe>
</body>
</html>
Run Code Online (Sandbox Code Playgroud)

以上是如何通过iframe编辑外部页面而不拒绝访问等的示例...

  • 当然,因为您的服务器正在获取远程页面而不是用户的浏览器,所以不会将cookie发送到远程页面.因人而异. (11认同)
  • @basysmith请注意:存在"同源策略"存在的原因,而这个答案的提议并不能免除它. (6认同)
  • @geon:但浏览器不会将外域的cookie发送到您的PHP脚本 (2认同)

zup*_*upa 32

我觉得这样清洁:

var $iframe = $("#iframeID").contents();
$iframe.find('selector');
Run Code Online (Sandbox Code Playgroud)


小智 30

使用

iframe.contentWindow.document
Run Code Online (Sandbox Code Playgroud)

代替

iframe.contentDocument
Run Code Online (Sandbox Code Playgroud)

  • 如今,即使从控制台也无法运行 (16认同)
  • 我相信它只适用于其他域名,如果你是从控制台进行的.从脚本中,不允许访问. (12认同)

And*_*ech 26

您需要将事件附加到iframe的onload处理程序,并在那里执行js,以便在访问之前确保iframe已完成加载.

$().ready(function () {
    $("#iframeID").ready(function () { //The function below executes once the iframe has finished loading
        $('some selector', frames['nameOfMyIframe'].document).doStuff();
    });
};
Run Code Online (Sandbox Code Playgroud)

以上将解决"尚未加载"的问题,但就权限而言,如果您在iframe中加载来自其他域的页面,则由于安全限制,您将无法访问该页面.

  • 关于此代码的几点注意事项:您应该使用iframe.contentDocument而不是.document,并且应该使用.load()而不是.ready()来避免等待.(不完美,但更好) (3认同)

B.A*_*lin 20

您可以使用window.postMessage在页面和他的iframe之间调用函数(是否跨域).

文档

page.html中

<!DOCTYPE html>
<html>
<head>
    <title>Page with an iframe</title>
    <meta charset="UTF-8" />
    <script src="http://code.jquery.com/jquery-1.10.2.min.js"></script>
    <script>
    var Page = {
        id:'page',
        variable:'This is the page.'
    };

    $(window).on('message', function(e) {
        var event = e.originalEvent;
        if(window.console) {
            console.log(event);
        }
        alert(event.origin + '\n' + event.data);
    });
    function iframeReady(iframe) {
        if(iframe.contentWindow.postMessage) {
            iframe.contentWindow.postMessage('Hello ' + Page.id, '*');
        }
    }
    </script>
</head>
<body>
    <h1>Page with an iframe</h1>
    <iframe src="iframe.html" onload="iframeReady(this);"></iframe>
</body>
</html>
Run Code Online (Sandbox Code Playgroud)

Iframe.html的

<!DOCTYPE html>
<html>
<head>
    <title>iframe</title>
    <meta charset="UTF-8" />
    <script src="http://code.jquery.com/jquery-1.10.2.min.js"></script>
    <script>
    var Page = {
        id:'iframe',
        variable:'The iframe.'
    };

    $(window).on('message', function(e) {
        var event = e.originalEvent;
        if(window.console) {
            console.log(event);
        }
        alert(event.origin + '\n' + event.data);
    });
    $(window).on('load', function() {
        if(window.parent.postMessage) {
            window.parent.postMessage('Hello ' + Page.id, '*');
        }
    });
    </script>
</head>
<body>
    <h1>iframe</h1>
    <p>It's the iframe.</p>
</body>
</html>
Run Code Online (Sandbox Code Playgroud)