Есть ли на стороне клиента способ определения X-Frame-Options? - PullRequest
38 голосов
/ 31 октября 2011

Есть ли хороший способ определить, когда страница не будет отображаться во фрейме из-за заголовка X-Frame-Options?Я знаю, что могу запросить страницу на стороне сервера и найти заголовок, но мне было любопытно, есть ли в браузере какой-либо механизм для обнаружения этой ошибки.

Ответы [ 8 ]

12 голосов
/ 18 февраля 2014

ОК, этот файл старый, но все еще актуален.

Факт: Когда iframe загружает URL, заблокированный X-Frame-Options, время загрузки очень короткое.

Hack: Так что, если перегрузка происходит немедленно, я знаю, что это , вероятно, проблема 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);
7 голосов
/ 20 апреля 2012

Отказ от ответственности: этот ответ, который я написал в 2012 году (в то время Chrome был версией ~ 20), устарел, и я буду хранить его здесь только в исторических целях.Читайте и используйте на свой страх и риск.


Хорошо, это немного старый вопрос, но вот что я выяснил (это не полный ответ) для Chrome / Chromium.

способ определить, загружен ли фрейм, указывающий на внешний адрес, - просто попытаться обратиться к его содержимому или документу.

вот код, который я использовал:

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.

проблема здесь в том, что я назвал "тогда,потом".Я еще не выяснил, на что положиться, какое событие подписать, чтобы найти, когда самое подходящее время для выполнения теста.

0 голосов
/ 02 мая 2017

Инструменты онлайн-тестирования могут быть полезны. Я использовал https://www.hurl.it/. Вы можете ясно видеть заголовок ответа. Ищите X-frame-option. если значение отрицать - оно не будет отображаться в iframe. одно и то же происхождение - только из одного домена, allow- позволит с определенных сайтов.

Если вы хотите попробовать другой инструмент, вы можете просто зайти в Google, чтобы получить «http запрос теста онлайн».

0 голосов
/ 23 июня 2016

Это основано на ответе @ Iftach , но немного менее хакерски.

Он проверяет, есть ли iframe.contentWindow.length > 0, что указывает на успешную загрузку iframe.

Кроме того, он проверяет, произошло ли событие iframe onload в течение 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. Я не тестировал его в других браузерах.

0 голосов
/ 22 июня 2016

Вот как я проверил 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.Когда у вас есть значение, вы можете использовать его в соответствующей логике.

0 голосов
/ 19 июля 2015

Этого можно достичь с помощью

a) Создать новый IFrame с помощью CreateElement

b) Установить его отображение как «none»

c) Загрузить URL-адрес черезатрибут src

d) Чтобы дождаться загрузки iframe, используйте метод SetTimeOut для задержки вызова функции (я задержал вызов на 10 секунд)

e) В этой функциипроверьте длину ContentWindow.

f) если длина> 0, то URL-адрес загружен, иначе URL-адрес не загружен из-за X-Frame-Options

Ниже приведен пример кода:

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');
}
}
0 голосов
/ 13 февраля 2012

По крайней мере, в Chrome вы можете заметить сбой загрузки, потому что событие iframe.onload не запускается.Вы можете использовать это в качестве индикатора того, что страница может не разрешать iframing.

0 голосов
/ 21 ноября 2011

Единственное, о чем я могу думать, это прокси-запрос AJAX для URL, затем посмотреть на заголовки, и, если у него нет X-Frame-Options, показать его в iframe. Далеко от идеала, но лучше, чем ничего.

...