提问人:Newtang 提问时间:10/31/2011 更新时间:5/2/2017 访问量:27925
有没有客户端方法来检测 X-Frame-Options?
Is there a client-side way to detect X-Frame-Options?
问:
有没有什么好的方法可以检测页面何时由于 X-Frame-Options 标头而无法显示在框架中?我知道我可以在服务器端请求页面并查找标题,但我很好奇浏览器是否有任何机制来捕获此错误。
答:
我唯一能想到的就是代理 url 的 AJAX 请求,然后查看标头,如果它没有 X-Frame-Options,则在 iframe 中显示它。远非理想,但总比没有好。
评论
至少在 Chrome 中,您可以注意到加载失败,因为 iframe.onload 事件未触发。您可以将其用作页面可能不允许 iframing 的指示器。
评论
免责声明:我在 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
这里的问题是我所说的“然后,以后”。我还没有弄清楚该依靠什么,什么时候是执行测试的好时机来寻找哪个事件。
评论
好吧,这个很旧,但仍然相关。
事实:当 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);
评论
这可以通过以下方式实现
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');
}
}
这就是我检查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 的值。一旦你有了这个值,你就可以在适当的逻辑中使用它。
评论
Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://www.openstreetmap.org/. (Reason: CORS header 'Access-Control-Allow-Origin' missing).
这是基于 @Iftach 的回答,但稍微不那么棘手。
它会检查这是否表明 iframe 已成功加载。iframe.contentWindow.length > 0
此外,它还会检查 iframe 事件是否在 5 秒内触发,并发出警报。这捕获了混合内容加载失败的情况(尽管以一种黑客的方式)。onload
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 上的当前版本。我没有在其他浏览器中测试过它。
评论
在线测试工具可能很有用。 我用 https://www.hurl.it/。 您可以清楚地看到响应标头。 寻找 X-frame-option。if value is deny - 它不会显示在 iframe 中。 同一来源 - 仅来自同一域, allow- 将允许来自特定网站。
如果您想尝试其他工具,只需在谷歌上搜索“http request test online”即可。
评论
Same-origin
frame.contentWindow
frame.contentDocument