javascript - sameorigin - x-frame-options htaccess
¿Hay una forma del lado del cliente para detectar X-Frame-Options? (8)
¿Hay alguna forma de detectar cuándo una página no se mostrará en un marco debido al encabezado X-Frame-Options? Sé que puedo solicitar la página del servidor y buscar el encabezado, pero tenía curiosidad si el navegador tiene algún mecanismo para detectar este error.
Al menos en Chrome, puede notar que no se carga porque el evento iframe.onload no se activa. Podría usar eso como un indicador de que la página podría no permitir iframing.
Así es como había comprobado X-Frames-Options para uno de mis requisitos. Al cargar una página JSP, puede usar AJAX para enviar una solicitud asincrónica a la URL específica de la siguiente manera:
var request = new XMLHttpRequest();
request.open(''GET'', <insert_URL_here>, false);
request.send(null);
Una vez hecho esto, puede leer los encabezados de respuesta recibidos de la siguiente manera:
var headers = request.getAllResponseHeaders();
Puede iterar sobre esto para averiguar el valor de X-Frames-Options. Una vez que tenga el valor, puede usarlo en una lógica apropiada.
Esto se basa en la respuesta de , pero es un poco menos hacky.
Comprueba si iframe.contentWindow.length > 0
lo que sugeriría que el iframe se ha cargado correctamente.
Además, comprueba si el evento iframe onload
se ha activado en 5 segundos y también lo alerta. Esto capta la carga fallida de contenido mixto (de una manera aunque sea hacky).
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);
Demostración en vivo aquí - https://jsfiddle.net/dvdsmpsn/7qusz4q3/ - para que pueda probarla en los navegadores correspondientes.
Al momento de escribir esto, funciona en la versión actual en Chrome, Safari, Opera, Firefox, Vivaldi e Internet Explorer 11. No lo he probado en otros navegadores.
Esto se puede lograr a través de
a) Crea un nuevo IFrame a través de CreateElement
b) Establecer su visualización como ''ninguno''
c) Cargar la URL a través del atributo src
d) Para esperar a que se cargue el iframe, use el método SetTimeOut para retrasar una llamada de función (había demorado la llamada en 10 segundos)
e) En esa función, verifique la longitud de ContentWindow.
f) si la longitud> 0, la URL está cargada, la URL no se carga debido a X-Frame-Options
A continuación se muestra el código de muestra:
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'');
}
}
Las herramientas de prueba en línea pueden ser útiles. Usé https://www.hurl.it/ . puedes ver claramente el encabezado de respuesta. Busque la opción X-frame. si value es deny - No se mostrará en iframe. mismo origen, solo desde el mismo dominio, permitir, permitirá desde sitios web específicos.
Si desea probar otra herramienta, puede buscar en google ''prueba de solicitud http en línea''.
Lo único que se me ocurre es proxy una solicitud de AJAX para la url, luego mira los encabezados, y si no tiene X-Frame-Options, entonces muéstralo en el iframe. Lejos de ser ideal, pero mejor que nada.
OK, este es viejo pero sigue siendo relevante.
Hecho: cuando un iframe carga una url que está bloqueada por un X-Frame-Options, el tiempo de carga es muy corto.
Hack: Entonces, si la carga ocurre inmediatamente, sé que probablemente sea un problema de X-Frame-Options.
Descargo de responsabilidad: Este es probablemente uno de los códigos más ''hackiest'' que he escrito, así que no esperes mucho:
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);
Descargo de responsabilidad: esta respuesta que escribí en 2012 (Chrome era la versión ~ 20 en ese momento) está desactualizada y la mantendré aquí solo con fines históricos. Lea y use bajo su propio riesgo.
Ok, esta es una pregunta un poco vieja, pero esto es lo que descubrí (no es una respuesta completa) para Chrome / Chromium.
la manera de detectar si un marco que apunta a una dirección en el extranjero se ha cargado es simplemente para tratar de acceder a su contenidoWindow o documento.
aquí está el código que utilicé:
element.innerHTML = ''<iframe class="innerPopupIframe" width="100%" height="100%" src="''+href+''"></iframe>'';
myframe = $(element).find(''iframe'');
Entonces despúes:
try {
var letstrythis = myframe.contentWindow;
} catch(ex) {
alert(''the frame has surely started loading'');
}
el hecho es que si las X-Frame-Options prohíben el acceso, entonces se podrá acceder a myFrame.contentWindow
.
el problema aquí es lo que llamé "luego, más tarde". Todavía no me he dado cuenta de en qué confiar, qué evento subscribir para encontrar cuándo es el buen momento para realizar la prueba.