检查JS是否可以访问iframe的文档

Check if JS has access to an iframe's document

本文关键字:iframe 文档 访问 JS 是否 检查      更新时间:2023-09-26

有什么标准方法可以知道我的脚本是否可以访问iframe的文档吗?

我在网上找不到任何东西,所以我想出了这个:

function checkifr() {
    function errHandler() {
        alert('Error. Try again later.');
    }
    var ifr = $('#ifr')[0]; //the iframe DOM element
    try {
        var d = ifr.contentWindow || ifr.contentDocument;
        if (!d) {
            errHandler();
            return false;
        }
        var b = $('#ifr').contents().find('body');
        //... manipulate iframe content
    } catch(e) {
        errHandler();
    }
}

它有效,当我尝试访问iframe的内容时,Firefox 会抛出错误并最终进入catch块。Chrome 在控制台中显示Unsafe JavaScript attempt to access frame警告,但从未进入catch块,它似乎会为这些尝试返回null,因此初始if (!d)会处理它。Opera和IE的行为类似于FF。 编辑:使用上面的代码,现在Chrome返回一个"空"窗口对象(没有属性),它不会触发我的if块。检查Esailija的答案,它可以很好地跨浏览器工作!

这是小提琴

无法测试iframesrcwindow.location

合理背景:这是因为这个函数是我正在开发的一个小图像上传插件的一部分(使用iframe作为目标,因为 IE<9 不支持 XHR2),目标主要是验证连接错误/超时/等。这些错误的默认浏览器页面受同一来源监管的约束,因此本问题的目的。我不想发送 ajax 调用来检查页面是否可用,因为我想验证提交请求本身。jQuery的.load处理器不会因错误而触发,jQuery的.error和onerror HTML属性不适用于此。此处提供了工作脚本的插图,但您可以完全忽略它,只需回答下面的问题。

请注意,上面的块仅用于说明为什么我不能使用iframe.src

我确实认为应该有一种更简单/标准的方法来检查iframe的"可访问性",但我在网上或 SO 上找不到任何东西,除了半解决方案,这些解决方案只是检查iframe.src并且不适用于很多情况。如果我的黑客try/catch块被认为是技术上"干净"的解决方案,如果没有找到更好的选择,其他人可能会重复使用它。

那么是否有任何标准或更简单的方法或jQuery插件来检查我的脚本是否可以访问iframe的文档,而无需将iframesrcwindow.location进行比较?如果可能,控制台中没有try/catch块和错误/警告。

这是另一种选择,没有尝试捕获就无法真正做到这一点。

测试 http://jsfiddle.net/LHjwZ/11/

function checkIframe( ifr ) {
    var key = ( +new Date ) + "" + Math.random();
    try {
        var global = ifr.contentWindow;
        global[key] = "asd";
        return global[key] === "asd";
    }
    catch( e ) {
        return false;
    }
}

这里有一个想法,无论访问是否引发异常,它都会起作用:

function checkFrameAccess(ifr) {
    try {
        var doc = ifr.contentDocument || ifr.contentWindow.document;
        var origClass = doc.body.className;
        var newClass = origClass += " xxxxx";
        doc.body.className = newClass;
        var valid = doc.body.className == newClass;
        doc.body.className = origClass;
        return(valid);
    } catch(e) {
        return(false);
    }
}

如果他们抛出异常,您最终会进入异常处理程序并返回false . 如果它们没有引发异常,则测试是否可以实际修改帧中正文标记的 className。 如果修改有效,那么显然,您可以修改它。如果没有,那么它不会让您访问它。