Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/jquery/78.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何在不触发错误的情况下检测iframe是否可访问?_Javascript_Jquery_Security_Iframe_Exception Handling - Fatal编程技术网

Javascript 如何在不触发错误的情况下检测iframe是否可访问?

Javascript 如何在不触发错误的情况下检测iframe是否可访问?,javascript,jquery,security,iframe,exception-handling,Javascript,Jquery,Security,Iframe,Exception Handling,基本上,我加载了一个iframe,只要它触发onload事件,就可以从父级访问它。它工作得很好,但是当iframe的内容不再在同一个域上时,我会出错,这是意料之中的 唯一的问题是,我想抑制这些错误。不幸的是,try/catch无法捕获此异常,并且尝试访问这些属性中的任何一个来验证它们会再次产生相同的错误,因此无法达到目的 有没有可靠的方法可以让我简单地检查iframe内容是否可以访问而不产生任何错误消息 谢谢 编辑: 为了上下文,不要让人们用无关的评论来回答;我正在编写一个小脚本,根据ifram

基本上,我加载了一个iframe,只要它触发onload事件,就可以从父级访问它。它工作得很好,但是当iframe的内容不再在同一个域上时,我会出错,这是意料之中的

唯一的问题是,我想抑制这些错误。不幸的是,try/catch无法捕获此异常,并且尝试访问这些属性中的任何一个来验证它们会再次产生相同的错误,因此无法达到目的

有没有可靠的方法可以让我简单地检查iframe内容是否可以访问而不产生任何错误消息

谢谢

编辑:

为了上下文,不要让人们用无关的评论来回答;我正在编写一个小脚本,根据iframes文档的高度自动调整父页面上iframe的大小。当用户单击iframe中指向域外的链接时,我显然无法检测页面的高度,但我更希望不要在控制台中触发任何错误,而是优雅地处理异常


我知道有一些解决办法,我只是想通过弄清楚是否有一种优雅的方式来处理这类案件来教育自己,而不是仅仅求助于一个丑陋的解决办法。

你可以使用
窗口获得
iframe
的当前URL。frames['frame\u name'].contentWindow.location.href

如果用户已经离开了你的域,那么就没有办法了。对不起


更多信息。

您不能从父级访问
src
属性吗

据我所知,
iframe
元素属于“父”页面,而包含在iframe中的
window
对象属于“子”页面

这对我很有用:

<html>
<head>
</head>
<body>
<iframe id="ifr" name="ifr" src="http://www.example.com"></iframe>
<input type="button" onclick="showSrc()" value="showSrc" />
<input type="button" onclick="showHref()" value="showHref" />
<script>
    var ifr = document.getElementById('ifr');
    function showSrc() {
        // no warning
        alert(ifr.src);
    }
    function showHref() {
        // warning
        alert(window.frames['ifr'].contentWindow.location.href);
    }

</script>
</body>
</html>

var ifr=document.getElementById('ifr');
函数showSrc(){
//没有警告
警报(ifr.src);
}
函数showHref(){
//警告
警报(window.frames['ifr'].contentWindow.location.href);
}

好吧,这是一种过激的手段,不是很多,而是一种黑客手段,在你的情况下可能不太可能,但无论如何:

您可以在站点中所有试图访问opener(父框架)的页面中添加javascript,并将标志(bool stillOnMySite之类的变量)设置为true

然后

  • 基于时间:网站页面中的脚本每秒将标志设置为true,父iframe中的脚本每秒将标志设置为false。在setTimeOut(xxx,1)中轮询iframe。如果该标志再次为非真,则用户离开了您的网站,您不应轮询iframe。如果该标志为真,则用户仍在您的网站上,您可以轮询iframe

  • 基于点击:使用jquery作为不引人注目的javascript,网站页面中的脚本将监视页面中所有链接中的点击事件。如果链接超出了您的域,则会将父iframe中的标志设置为false

  • 当然,如果你不能在网站页面中添加脚本,所有的理论都会崩溃


    或者,我只是想:如果您的iframe总是从您的网站开始,那么无需修改您的网站页面,只需将父iframe的n°2解决方案注入iframe页面。

    如果您可以向您的域中的所有页面添加一点JavaScript,您希望加载到您可以使用的iframe中,不受同一原产地政策的限制。可能最简单的方法是让子窗口在加载时向父窗口发布消息,并使用该消息而不是
    onload
    。例如,您可以将以下内容添加到每个页面:

    if (window.parent) document.addEventListener( 'load', function() {
        window.parent.postMessage( "child loaded", "/" );
    }, false );
    
    这将在页面加载到具有相同原点的框架时向父窗口发布消息。然后你会像这样听它:

    var iframe = document.getElementById( 'your-iframe' );
    var origin = window.location.protocol + '://' + window.location.host;
    if (window.location.port != 80) origin += ':' + window.location.port;
    
    window.addEventListener( 'message', function (event) {
        if (event.source != iframe.contentWindow
                || event.origin != origin || event.data != "child loaded")
            return;
    
        // do here what you used to do on the iframe's load event
    }, false );
    

    请注意,这些示例使用W3C/Netscape事件API,因此在9版之前的Internet Explorer中不起作用。

    您能告诉我如何设置iframe的src吗?
    如果您使用javascript动态更改它,您的问题很容易处理。

    var isXdm = false;
    function setSrc(id,src){
       //detect whether src is cross domain then set the variable isXdm
       ...
    }
    
    即便如此,我也不认为这是解决这个问题的好办法。

    希望任何人都能找到更好的解决方案。

    如果IFRAME的href没有指向与父页面相同的协议和主机,那么不呈现IFRAME(在父页面中)怎么样?我可能误解了你是拥有这两个网站,还是只拥有其中一个(以及哪一个)。但是,如果您拥有父页面站点,您应该能够做到这一点,无论是在服务器上(甚至在包含IFRAME之前),还是在客户端的某个位置(页面加载/文档加载)。

    尝试以下操作:

    var $frame = $("#frameId"); // swap with the id of the iframe
    try {
        var canAccess = $frame.contents();
        if(!!canAccess) {
           // same domain yay you have access
           // do your thing here
        }
    }
    catch( e ) {
        // bummer can't do much with it
        return false;
    }
    
    编辑:添加一个try-and-catch,任何错误都不会返回false。

    也可以使用常规JS进行编辑:

    函数iframe\u可访问(theiframe){
    var thedoc,debug=true;
    试一试{
    thedoc=(theiframe.contentWindow | | theiframe.contentDocument);
    如果(文档)
    thedoc=thedoc.document;
    如果(调试)
    console.log('Accessible');
    返回true;
    }
    捕捉(错误){
    如果(调试)
    console.log(“由于\n”+错误而无法访问);
    返回false;
    }
    }
    var elm=document.querySelector('iframe');//当然,如果它存在的话
    
    console.log(iframe_-accessible(elm))感谢您的回复。我知道我能做到,但这不是我的问题。问题是,当iframe在父域之外提供内容时,如果浏览器没有向我抛出权限错误,我甚至无法“尝试”获取此信息。我想超越这些错误,基本上就像你使用try/catch短语一样,只是出于某种神奇的原因,try/catch没有捕捉到这些类型的错误(至少在Firefox中没有)。我认为没有办法抑制这种浏览器错误。404个AJAX请求也是如此。@Naatan:最坏的情况是,您可以在0毫秒内安排一个
    setTimeout
    来解决这个问题