45

由于 X-Frame-Options 标头,有什么好的方法可以检测页面何时不会显示在框架中?我知道我可以请求页面服务器端并查找标头,但我很好奇浏览器是否有任何机制来捕获此错误。

4

8 回答 8

13

好的,这个很旧但仍然相关。

事实: 当 iframe 加载被 X-Frame-Options 阻止的 url 时,加载时间非常短。

哈克: 所以如果加载立即发生,我知道这可能是 X-Frame-Options 问题。

免责声明: 这可能是我编写的“最骇人听闻”的代码之一,所以不要期望太多:

var timepast=false; 
var iframe = document.createElement("iframe");

iframe.style.cssText = "position:fixed; top:0px; left:0px; bottom:0px; right:0px; width:100%; height:100%; border:none; margin:0; padding:0; overflow:hidden; z-index:999999;";
iframe.src = "http://pix.do"; // This will work
//iframe.src = "http://google.com"; // This won't work
iframe.id = "theFrame";

// If more then 500ms past that means a page is loading inside the iFrame
setTimeout(function() {
    timepast = true;
},500);

if (iframe.attachEvent){
    iframe.attachEvent("onload", function(){
    if(timepast) {
            console.log("It's PROBABLY OK");
        }
        else {
            console.log("It's PROBABLY NOT OK");
        }
    });
} 
else {
    iframe.onload = function(){
        if(timepast) {
            console.log("It's PROBABLY OK");
        }
        else {
            console.log("It's PROBABLY NOT OK");
        }
    };
}
document.body.appendChild(iframe);
于 2014-02-18T11:17:00.820 回答
7

免责声明:我在 2012 年写的这个答案(当时的 Chrome 是 ~20 版)已经过时,我将它保留在这里仅用于历史目的。阅读和使用风险自负。


好的,这是一个有点老的问题,但这是我对 Chrome/Chromium 的发现(这不是一个完整的答案)。

检测指向外部地址的框架是否已加载的方法只是尝试访问其 contentWindow 或文档。

这是我使用的代码:

element.innerHTML = '<iframe class="innerPopupIframe" width="100%" height="100%" src="'+href+'"></iframe>';
myframe = $(element).find('iframe');

然后,稍后:

try {
    var letstrythis = myframe.contentWindow;
} catch(ex) {
    alert('the frame has surely started loading');
}

事实是,如果 X-Frame-Options 禁止访问,那么myFrame.contentWindow将是可访问的。

这里的问题是我所说的“然后,以后”。我还没有弄清楚要依赖什么,订阅哪个事件来查找何时是执行测试的好时机。

于 2012-04-20T15:13:02.547 回答
2

这是基于@Iftach的回答,但不那么老套。

它检查是否iframe.contentWindow.length > 0表明 iframe 已成功加载。

此外,它还会检查 iframeonload事件是否在 5 秒内触发并发出警报。这捕获了混合内容的失败加载(尽管以一种骇人听闻的方式)。

var iframeLoaded = false;
var iframe = document.createElement('iframe');

// ***** SWAP THE `iframe.src` VALUE BELOW FOR DIFFERENT RESULTS ***** //
// iframe.src = "https://davidsimpson.me"; // This will work
iframe.src = "https://google.com"; // This won't work

iframe.id = 'theFrame';
iframe.style.cssText = 'position:fixed; top:40px; left:10px; bottom:10px;'
 + 'right:10px; width:100%; height:100%; border:none; margin:0; padding:0; overflow:hidden; z-index:999999;';

var iframeOnloadEvent = function () {
    iframeLoaded = true;
  var consoleDiv = document.getElementById('console');
    if (iframe.contentWindow.length > 0) {
    consoleDiv.innerHTML = '✔ Content window loaded: ' + iframe.src;
    consoleDiv.style.cssText = 'color: green;'
    } else {
    consoleDiv.innerHTML = '✘ Content window failed to load: ' + iframe.src;
    consoleDiv.style.cssText = 'color: red;'
    }
} 

if (iframe.attachEvent){
    iframe.attachEvent('onload', iframeOnloadEvent);
} else {
    iframe.onload = iframeOnloadEvent;
}
document.body.appendChild(iframe);

// iframe.onload event doesn't trigger in firefox if loading mixed content (http iframe in https parent) and it is blocked.
setTimeout(function () {
    if (iframeLoaded === false) {
        console.error('%c✘ iframe failed to load within 5s', 'font-size: 2em;');
    consoleDiv.innerHTML = '✘ iframe failed to load within 5s: ' + iframe.src;
    consoleDiv.style.cssText = 'color: red;'    
  }
}, 5000);

现场演示 - https://jsfiddle.net/dvdsmpsn/7qusz4q3/ - 这样您就可以在相关浏览器中对其进行测试。

在撰写本文时,它适用于 Chrome、Safari、Opera、Firefox、Vivaldi 和 Internet Explorer 11 上的当前版本。我还没有在其他浏览器中测试过它。

于 2016-06-22T23:12:36.750 回答
0

我唯一能想到的就是为url代理一个AJAX请求,然后查看标头,如果它没有X-Frame-Options,则将其显示在iframe中。远非理想,但总比没有好。

于 2011-11-21T02:16:43.693 回答
0

至少在 Chrome 中,您会注意到加载失败,因为 iframe.onload 事件没有触发。您可以将其用作页面可能不允许 iframe 的指示。

于 2012-02-13T00:06:16.207 回答
0

在线测试工具可能有用。我使用了 https://www.hurl.it/。您可以清楚地看到响应标头。寻找 X 框架选项。如果值为拒绝 - 它不会显示在 iframe 中。相同的来源 - 仅来自同一域,允许 - 将允许来自特定网站。

如果您想尝试其他工具,您可以简单地在 google 上搜索“http request test online”。

于 2017-05-01T23:49:47.350 回答
-1

这可以通过

a) 通过 CreateElement 创建一个新的 IFrame

b) 将其显示设置为“无”

c) 通过 src 属性加载 URL

d) 为了等待 iframe 加载,使用 SetTimeOut 方法来延迟函数调用(我已经将调用延迟了 10 秒)

e) 在该函数中,检查 ContentWindow 长度。

f) 如果长度 > 0,则加载 url,否则由于 X-Frame-Options 未加载 URL

下面是示例代码:

function isLoaded(val) {
var elemId = document.getElementById('ctlx');
if (elemId != null)
    document.body.removeChild(elemId);


var obj= document.createElement('iframe');

obj.setAttribute("id", "ctlx");

obj.src = val;
obj.style.display = 'none';

document.body.appendChild(obj);

setTimeout(canLoad, 10000);  

}

function canLoad() {
//var elemId = document.getElementById('ctl100');
var elemId = document.getElementById('ctlx');
if (elemId.contentWindow.length > 0) {
    elemId.style.display = 'inline';

}

else {
    elemId.src = '';
    elemId.style.display = 'none';
    alert('not supported');
}
}
于 2015-07-19T15:36:31.953 回答
-1

这就是我检查 X-Frames-Options 以满足我的要求之一的方式。在加载 JSP 页面时,您可以使用 AJAX 向特定 URL 发送异步请求,如下所示:

var request = new XMLHttpRequest();
request.open('GET', <insert_URL_here>, false);
request.send(null);

完成后,您可以读取收到的响应标头,如下所示:

var headers = request.getAllResponseHeaders();

然后,您可以对其进行迭代以找出 X-Frames-Options 的值。一旦你有了这个值,你就可以在适当的逻辑中使用它。

于 2016-06-22T07:40:12.033 回答