Javascript 是否有客户端方法来检测 X-Frame-Options?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/7950184/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-24 04:10:39  来源:igfitidea点击:

Is there a client-side way to detect X-Frame-Options?

javascripthtmlbrowserframex-frame-options

提问by Newtang

Is there any good way to detect when a page isn't going to display in a frame because of the X-Frame-Options header? I know I can request the page serverside and look for the header, but I was curious if the browser has any mechanism for catching this error.

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

回答by Iftach

OK, this one is old but still relevant.

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

Fact:When an iframe loads a url which is blocked by a X-Frame-Options the loading time is very short.

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

Hack:So if the onload occurs immediately I know it's probablya X-Frame-Options issue.

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

Disclaimer:This is probably one of the 'hackiest' code I've written, so don't expect much:

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

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);

回答by BiAiB

Disclaimer: this answer I wrote in 2012(Chrome was version ~20 at that time) is outdated and I'll keep it here for historical purposes only. Read and use at your own risk.

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



Ok, this is a bit old question, but here's what I found out (it's not a complete answer) for Chrome/Chromium.

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

the way do detect if a frame pointing to a foreign address has loaded is simply to try to access its contentWindow or document.

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

here's the code I used:

这是我使用的代码:

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

then, later:

然后,后来:

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

the fact is, if the X-Frame-Options forbid access, then myFrame.contentWindowwill be accessible.

事实是,如果 X-Frame-Options 禁止访问,则myFrame.contentWindow可以访问。

the problem here is what I called "then, later". I haven't figured out yet on what to rely, which event to subsribe to find when is the good time to perform the test.

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

回答by dvdsmpsn

This is based on @Iftach's answer, but is a slightly less hacky.

这是基于@Iftach的答案,但稍微不那么笨拙。

It checks to see if iframe.contentWindow.length > 0which would suggest that the iframe has successfully loaded.

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

Additionally, it checks to see if the iframe onloadevent has fired within 5s and alerts that too. This catches failed loading of mixed content (in an albeit hacky manner).

此外,它还会检查 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);

Live demo here - https://jsfiddle.net/dvdsmpsn/7qusz4q3/- so you can test it in the relevant browsers.

现场演示 - https://jsfiddle.net/dvdsmpsn/7qusz4q3/- 所以你可以在相关浏览器中测试它。

At time of writing, it works on the current version on Chrome, Safari, Opera, Firefox, Vivaldi & Internet Explorer 11. I've not tested it in other browsers.

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

回答by OlgaY

Online test tools might be useful. I used https://www.hurl.it/. you can clearly see the response header. Look for X-frame-option. if value is deny - It will not display in iframe. same origin- only from the same domain, allow- will allow from specific websites.

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

If you want to try another tool, you can simply google for 'http request test online'.

如果你想尝试其他工具,你可以简单地谷歌搜索“http请求在线测试”。

回答by Newtang

The only thing I can think of is to proxy an AJAX request for the url, then look at the headers, and if it doesn't have X-Frame-Options, then show it in the iframe. Far from ideal, but better than nothing.

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

回答by apenwarr

At least in Chrome, you can notice the failure to load because the iframe.onload event doesn't trigger. You could use that as an indicator that the page might not allow iframing.

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

回答by Sivakumar Sundaresan

This can be achieved through

这可以通过

a) Create a new IFrame through CreateElement

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

b) Set its display as 'none'

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

c) Load the URL through the src attribute

c) 通过 src 属性加载 URL

d) In order to wait for the iframe to load, use the SetTimeOut method to delay a function call (i had delayed the call by 10 sec)

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

e) In that function, check for the ContentWindow length.

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

f) if the length > 0, then the url is loaded else URL is not loaded due to X-Frame-Options

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

Below is the sample code:

下面是示例代码:

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');
}
}

回答by Aditya Gupta

This is how I had checked for X-Frames-Options for one of my requirements. On load of a JSP page, you can use AJAX to send an asynchronous request to the specific URL as follows:

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

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

After this is done, you can read the response headers received as follows:

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

var headers = request.getAllResponseHeaders();

You can then iterate over this to find out the value of the X-Frames-Options. Once you have the value, you can use it in an appropriate logic.

然后您可以迭代它以找出 X-Frames-Options 的值。一旦获得了值,就可以在适当的逻辑中使用它。