html - example - iframe size
canje de iframe entre dominios (9)
¿Cómo cambio el tamaño de un iframe de otro dominio?
-Editar
Desplácese hacia abajo para ver algunas soluciones ... o lea sobre cómo NO hacer esto: D
Después de muchas horas de pirateo de código, la conclusión es que no se puede acceder a nada dentro del iframe, incluso las barras de desplazamiento que se renderizan en mi dominio. He intentado muchas técnicas sin ningún resultado.
Para ahorrarte tiempo, no vayas por esta ruta solo usa sendMessages para comunicaciones entre dominios. Hay complementos para HTML <5 que uso: vaya al final para ver un buen ejemplo :)
Los últimos días he intentado integrar un iframe en un sitio. Esta es una solución a corto plazo, mientras que la otra parte se desarrolla y API (podría llevar meses ...) Y debido a que esta es una solución a corto plazo, queremos utilizar easyXDM. Tengo acceso al otro dominio, pero es bastante difícil pedirles que lo hagan. agregue el encabezado p3p tal como es .....
3 iframes
La solución más cercana que encontré fueron los 3 iframes, pero va mental de Chrome y Safari, así que no puedo usar eso.
abrir en cromo
http://css-tricks.com/examples/iFrameResize/crossdomain.php#frameId=frame-one&height=1179
Mida las barras de desplazamiento
Encontré otra publicación sobre cómo usar la altura de desplazamiento para intentar redimensionar el formulario ... en teoría funciona bien pero no pude aplicarlo correctamente usando la altura de desplazamiento de iframes.
document.body.scrollHeight
Que obvio usa la altura de los cuerpos (no puede acceder a estas propiedades el 100% se basa en los clientes muestran canvaz y no la altura del documento x-domains)
Intenté usar jquery para obtener la altura de los iframes
$(''#frameId'').Height()
$(''#frameId'').clientHeight
$(''#frameId'').scrollHeight
devuelve valores diferentes en cromo y es decir, o simplemente no tiene ningún sentido. El problema es que todo lo que está dentro del marco está denegado, incluso la barra de desplazamiento ...
Estilos computados
Pero si inspecciono y elemento en cromo del iframe, bladdy me muestra las dimensiones de los documentos dentro del iframe (usando jquery x-domain para obtener iframe.heigh - access denied) No hay nada en el CSS calculado
Ahora, ¿cómo calcula Chrome eso? (edit-browser vuelve a renderizar la página usando su compilación en el motor de renderizado para calcular todas estas configuraciones, pero no está adjuntado en ninguna parte para evitar el fraude entre dominios ... así que ...)
HTML4
Leí la especificación de HTML4.x y dice que debe haber valores de solo lectura expuestos a través de document.element, pero se niega el acceso a través de jquery
Marco Proxy
Bajé la ruta de proxy del sitio y calculando qué es correcto ... hasta que un usuario inicia sesión en el iframe y el proxy obtiene una página de inicio de sesión en lugar del contenido real. También para algunos llamar a la página dos veces no es aceptable
http://www.codeproject.com/KB/aspnet/asproxy.aspx
http://www.johnchapman.name/aspnet-proxy-page-cross-domain-requests-from-ajax-and-javascript/
Re-Renderiza la página
No llegué hasta aquí, pero hay motores de jScript que miran la fuente y vuelven a renderizar la página según el archivo fuente. pero requeriría piratear esos archivos ... y esa no es una situación ideal para las entidades comerciales ... y algunos invocan los applets java puros o la representación del servidor
http://en.wikipedia.org/wiki/Server-side_JavaScript
http://htmlunit.sourceforge.net/ <-java no jscript
EDITAR ACTUALIZACIÓN 09-2013
Todo esto puede hacerse con los sockets HTML5. Pero easyXDM es una gran alternativa para las páginas de quejas que no son HTML5.
Solución 1 ¡ Gran solución!
Usando easyXDM
En su servidor, configura una página en forma de
<html>
<head>
<script src="scripts/easyXDM.js" type="text/javascript"></script>
<script type="text/javascript" language="javascript">
var transport = new easyXDM.Socket(/** The configuration */{
remote: "http://www.OTHERDOMAIN.com/resize_intermediate.html?url=testpages/resized_iframe_1.html",
//ID of the element to attach the inline frame to
container: "embedded",
onMessage: function (message, origin) {
var settings = message.split(",");
//Use jquery on a masterpage.
//$(''iframe'').height(settings[0]);
//$(''iframe'').width(settings[1]);
//The normal solution without jquery if not using any complex pages (default)
this.container.getElementsByTagName("iframe")[0].style.height = settings[0];
this.container.getElementsByTagName("iframe")[0].style.width = settings[1];
}
});
</script>
</head>
<body>
<div id="embedded"></div>
</body>
y en el dominio de las personas que llaman solo necesitan agregar el html intermiedate_frame y easyXDM.js en el mismo lugar. Al igual que una carpeta principal, puede acceder a los directorios relativos o a una carpeta contenida solo para usted.
OPCIÓN 1
¡Si no quiere agregar scripts a todas las páginas, mire la opción 2!
Luego, pueden agregar un simple jscript al final de cada una de las páginas que necesita para cambiar el tamaño. No es necesario incluir easyxdm en cada una de estas páginas.
<script type="text/javascript">
window.onload = function(){ parent.socket.postMessage( (parseInt(document.body.clientHeight)) + "," + ( document.body.clientWidth ) ); };
</script>
He modificado los parámetros que envía. Si desea que el ancho funcione correctamente, las páginas del otro dominio deben incluir el ancho de la página en un estilo som, que tenga un aspecto similar a:
<style type="text/css">
html, body {
overflow: hidden;
margin: 0px;
padding: 0px;
background-color: rgb(75,0,85);
color:white;
width:660px
}
a {
color:white;
visited:white;
}
</style>
Esto funciona genial para mí Si el ancho no está incluido, entonces el marco se comporta de una manera un poco extraña y amable, intenta adivinar lo que debería ser ... y no se encogerá si lo necesita.
OPCION 2
Modificar el marco intermedio para sondear para cambios
Su marco intermedio debería verse más o menos así ..
<!doctype html>
<html>
<head>
<title>Frame</title>
<script type="text/javascript" src="easyXDM.js">
</script>
<script type="text/javascript">
var iframe;
var socket = new easyXDM.Socket({
//This is a fallback- not needed in many cases
swf: "easyxdm.swf",
onReady: function(){
iframe = document.createElement("iframe");
iframe.frameBorder = 0;
document.body.appendChild(iframe);
iframe.src = "THE HOST FRAME";
iframe.onchange = messageBack();
},
onMessage: function(url, origin){
iframe.src = url;
}
});
//Probe child.frame for dimensions.
function messageBack(){
socket.postMessage ( iframe.contentDocument.body.clientHeight + "," + iframe.contentDocument.body.clientWidth);
};
//Poll for changes on children every 500ms.
setInterval("messageBack()",500);
</script>
<style type="text/css">
html, body {
overflow: hidden;
margin: 0px;
padding: 0px;
width: 100%;
height: 100%;
}
iframe {
width: 100%;
height: 100%;
border: 0px;
}
</style>
</head>
<body>
</body>
</html>
El intervalo podría ser más eficiente para atacar si el tamaño ha cambiado y solo enviarlo si las dimensiones cambian debido a la publicación de mensajes cada 500 ms. ¡Si implementa esta verificación, puede cambiar la votación tan bajo como 50 ms! que te diviertas
Funciona en todos los navegadores y es rápido. Grandes características de depuración !!
Excellent Work to Sean Kinsey who made the script!!!
Solución 2 (funciona pero no es genial)
Entonces, básicamente, si tiene un acuerdo mutuo con el otro dominio, entonces puede agregar una biblioteca para manejar sendmessage. Si no tiene acceso al otro dominio ... Siga buscando más hacks, porque no pude encontrar o justificar completamente estos.
Entonces, el otro dominio incluirá estos en la etiqueta Head
<script src="scripts/jquery-1.5.2.min.js" type="text/javascript"></script>
<script src="scripts/jquery.postmessage.min.js" type="text/javascript"></script>
<script src="scripts/club.js" type="text/javascript"></script>
En el club.js solo hay algunas llamadas personalizadas que hice para cambiar el tamaño de las llamadas y contiene ...
$(document).ready(function () {
var parent_url = decodeURIComponent( document.location.hash.replace( /^#/, '''' ) ),link;
//Add source url hash to each url to authorise callback when navigating inside the frame.Without this clicking any links will break the communication and no messages will be received
$(''a[href]'').each(function(){
this.href = this.href + document.location.hash ;
});
//Get the dimensions and send back to calling page.
var h1 = document.body.scrollHeight;
var w1 = document.body.scrollWidth;
$.postMessage({ if_height: h1, if_width: w1 }, parent_url, parent );
});
Y tu página hará todo el trabajo y tendrá un buen guión ...
//This is almost like request.querystring used to get the iframe data
function querySt(param, e) {
gy = e.split("&");
for (i = 0; i < gy.length; i++) {
ft = gy[i].split("=");
if (ft[0] == param) {
return ft[1];
}
}
}
$(function () {
// Keep track of the iframe dimensions.
var if_height;
var if_width;
// Pass the parent page URL into the Iframe in a meaningful way (this URL could be
// passed via query string or hard coded into the child page, it depends on your needs).
src = ''http://www.OTHERDOAMIN.co.uk/OTHERSTARTPAGE.htm'' + ''#'' + encodeURIComponent(document.location.href),
// Append the Iframe into the DOM.
iframe = $(''<iframe " src="'' + src + ''" width="100%" height="100%" scrolling="no" frameborder="0"><//iframe>'').appendTo(''#iframe'');
// Setup a callback to handle the dispatched MessageEvent event. In cases where
// window.postMessage is supported, the passed event will have .data, .origin and
// .source properties. Otherwise, this will only have the .data property.
$.receiveMessage(function (e) {
// Get the height from the passsed data.
//var h = Number(e.data.replace(/.*if_height=(/d+)(?:&|$)/, ''$1''));
var h = querySt("if_height", e.data);
var w = querySt("if_width", e.data);
if (!isNaN(h) && h > 0 && h !== if_height) {
// Height has changed, update the iframe.
iframe.height(if_height = h);
}
if (!isNaN(w) && w > 0 && w !== if_width) {
// Height has changed, update the iframe.
iframe.width(if_width = w);
}
//For debugging only really- can remove the next line if you want
$(''body'').prepend("Recieved" + h + "hX" + w + "w .. ");
// An optional origin URL (Ignored where window.postMessage is unsupported).
//Here you must put the other domain.com name only! This is like an authentication to prevent spoofing and xss attacks!
}, ''http://www.OTHERDOMAIN.co.uk'');
});
OPCIÓN 3
Ahora es una pequeña biblioteca JS para administrar el cambio de tamaño de iFrames entre dominios, todavía requiere que iFrame tenga un poco de JavaScript, sin embargo, esto es solo 2.8k (765 bytes Gzip) de JS nativo que no tiene ninguna dependencia. y no hace nada hasta que lo llame la página padre. Esto significa que es un buen invitado en los sistemas de otras personas.
Este código usa mutationObserver para detectar cambios DOM y también busca eventos de cambio de tamaño, de modo que el iFrame sigue teniendo el mismo tamaño que el contenido. Funciona en IE8 +.
¿Estás buscando la altura de la página contenida en el iframe? Obtuve algo de javascript que comprueba la altura del contenido del iframe y luego establece la altura del iframe a la altura del contenido.
var Height = document.getElementById(''iFrameId'').contentWindow.document.body.scrollHeight;
document.getElementById(''iFrameId'').height = Height;
Sin embargo, esto solo funciona si la página que está mostrando en el iframe está en el mismo dominio. Si no es así, no puede acceder a la información requerida. Por lo tanto, el acceso denegó el error.
¿Has analizado los atributos de HTML5 "adecuados para el objeto"? Escala videos / imágenes al iframe, en lugar de escalar el iframe (es agradable si toma una imagen de tamaño mediano que termina teniendo un ancho de 5,000 píxeles). La opción "ajustar" (otros son "cubrir" y "llenar") utiliza un enfoque de tipo de buzón para ajustar la fuente y preservar las relaciones de aspecto. Para ver por menos HTML5, parece que hay una gran cantidad de polyfills disponibles. Este es genial, pero un error al final de Edge lo ha mantenido incompatible con New Nightmare de Microsoft durante aproximadamente un año, ahora: https://github.com/anselmh/object-fit
EDITAR: para evitar problemas de dominio cruzado, siempre puede hacer el trabajo en un Script de contenido de extensión de Chrome, ya que cree que es parte de la página en la que está pegando su iframe.
Después de buscar una gran cantidad de soluciones diferentes para esto, terminé escribiendo una pequeña biblioteca simple para tener en cuenta varios casos de uso diferentes. Como necesitaba una solución que admitiera varios iFrames generados por el usuario en una página de portal, el navegador admitido cambia el tamaño y podría hacer frente a la carga de JavaScript de la página de host después del iFrame. También agrego soporte para dimensionar al ancho y una función de devolución de llamada y permitir la anulación del body.margin, ya que es probable que desee tener este conjunto en cero.
https://github.com/davidjbradshaw/iframe-resizer
El código iframe es solo un pequeño JavaScript autocontenido, por lo que es un buen invitado en las páginas de otras personas.
El script se inicializa en la página de host con las siguientes opciones disponibles.
iFrameResize({
log : true, // For development
autoResize : true, // Trigering resize on events in iFrame
contentWindowBodyMargin: 8, // Set the default browser body margin style (in px)
doHeight : true, // Calculates dynamic height
doWidth : false, // Calculates dynamic width
enablePublicMethods : true, // Enable methods within iframe hosted page
interval : 32, // interval in ms to recalculate body height, 0 to disable refreshing
scrolling : false, // Enable the scrollbars in the iFrame
callback : function(messageData){ // Callback fn when message is received
$(''p#callback'').html(
''<b>Frame ID:</b> '' + messageData.iframe.id +
'' <b>Height:</b> '' + messageData.height +
'' <b>Width:</b> '' + messageData.width +
'' <b>Event type:</b> '' + messageData.type
);
}
});
El asunto es que no hay otra manera más que usar la mensajería entre dominios para esto, ya que necesita obtener la altura calculada de un documento en un dominio, a un documento en un dominio diferente.
Entonces, o haces esto usando postMessage
(funciona en todos los navegadores modernos), o pasas 5 minutos adaptando el ejemplo iframe de tamaño de easyXDM.
La otra parte realmente solo necesita copiar algunos archivos en su dominio y agregar una sola línea de código a su documento.
En lugar de usar scroll = no en el iframe, lo cambio a "auto". Entonces, obtengo el tamaño de la ventana real
$(window).height();
y usar eso como el atributo de altura del iframe.
Bueno, el resultado es ...
Nunca tendremos el desplazamiento "página", solo el desplazamiento "iframe". Cuando navegas, no importa quién es el desplazamiento, pero lo importante es que solo hay 1.
Bueno, existe el problema de que el usuario simplemente cambia el tamaño de la ventana mientras navega. Para resolver eso, uso:
setInterval(getDocHeight, 1);
¿Pensaste que esa solución causaría algún error? Me funciona, y en el iFrame tuve el contenido dinámico generado por php. Tengo miedo de futuros errores con eso ...
Hoy en día solo hay 4 soluciones que conozco:
- postMessage. Algunos navegadores no son compatibles por supuesto .
- window.location.hash manipulaciones. Creo que es la solución # 2 aquí.
- easyXDM
- window.name Transporte
Solo el tercero puede resolver muchos problemas. Por ejemplo , puede crear iFrame receptivo ; ciérralo desde adentro o puedes comunicarte con él . Pero para hacer eso necesita iFrame en Iframe y la solución de "cookies de terceros" (opcional).
Creé un artículo al respecto con un ejemplo: iFrame multidominio basado en eventos
Para cambiar el tamaño de un iframe, aquí hay un script simple:
esto va en la cabeza: (esto fue escrito para un script php, para html, cambiar el ''a'' y el '''' a ''...
<script type=''text/javascript''>
<!--
function resizeIframe(id){
/*
this.obj=obj
//this.obj.width=null
//this.obj.width=window.frames[/"sizeframe1/"].document.body.scrollWidth
this.obj.style.height=/"/" // for Firefox and Opera
setTimeout(/"this.obj.style.height=this.obj.contentWindow.document.body.scrollHeight+(notIE?heightOffset:0)/",10) // setTimeout required for Opera
*/
el=document.getElementById(id)
el.style.height=''200px'' // for Firefox and Opera
setTimeout(''el.style.height=el.contentWindow.document.body.scrollHeight+/"px/"'',1) // setTimeout required for Opera
}
// -->
</script>"
final de la cabeza
esto va en el cuerpo (recuerde, esto fue escrito para un script php, para html cambiar todo el ''hasta'' y el ''hasta'' ...)
<iframe onload=''resizeIframe(this.id)'' allowTransparency=/"true/" name=''ccpaymentwindow'' id=''sizeframe1'' marginwidth=''1'' marginheight=''1'' height=''700'' width=''690'' border=''0'' frameborder=''1'' scrolling=''no'' src=''ccmslink.php?variable1=" . $variable1 . "''></iframe>
bonificación: hay algunos consejos arriba. Como está configurado para php scripting, puedes hacer mucho con él ... para aprender más, hacer más ...
la clave para esto es "sizeframe1" .... para múltiples "resizers" en la misma página, copie el mismo script pero cambie el id en iframe y el nombre en el script en el encabezado, ¡y viola! tienes múltiples resizer en la misma página ... ¡funciona muy bien!
tienes phun.
Similar a lo que ha mencionado Sean, puede usar postMessage. He pasado tanto tiempo probando diferentes formas de cambiar el tamaño del iframe con dominios cruzados, pero no tuve suerte hasta que tropecé con esta gran publicación de David Walsh en el blog: http://davidwalsh.name/window-iframe
Esta es una combinación de mi código y la solución de David. Mi solución está orientada específicamente hacia el cambio de tamaño de iframes.
En la página secundaria, encuentre el alto de la página y páselo a la página principal (que contiene el iframe). Reemplaza elemento_id con tu elemento id (html, cuerpo, lo que sea).
<script>
function adjust_iframe_height(){
var actual_height = document.getElementById(''element_id).scrollHeight;
parent.postMessage(actual_height,"*");
//* allows this to post to any parent iframe regardless of domain
}
</script>
<body onload="adjust_iframe_height();">
//call the function above after the content of the child loads
En la ventana principal, agregue este código. Reemplace iframe_id con su ID de iframe:
<script>
// Create IE + others compatible event handler
var eventMethod = window.addEventListener ? "addEventListener" : "attachEvent";
var eventer = window[eventMethod];
var messageEvent = eventMethod == "attachEvent" ? "onmessage" : "message";
// Listen to message from child window
eventer(messageEvent,function(e) {
console.log(''parent received message!: '',e.data);
document.getElementById(''iframe_id'').height = e.data + ''px'';
},false);
</script>
Si abre la consola, verá la altura impresa en el registro de la consola. Esto te ayudará a depurar, y es por eso que lo dejé allí.
Lo mejor, Baker
HTTPS otro enlace obtiene altura para iframe autoheight
https://-a.com contenido:
<!DOCTYPE html>
<html>
<head>
<title>Test Page</title>
</head>
<body>
Test Page:
<hr/>
<iframe id="iframe" src="https://-b.com" style="width:100%;min-height:600px;border:none;" scrolling="no" ></iframe>
<script>
// browser compatibility: get method for event
// addEventListener(FF, Webkit, Opera, IE9+) and attachEvent(IE5-8)
var myEventMethod =
window.addEventListener ? "addEventListener" : "attachEvent";
// create event listener
var myEventListener = window[myEventMethod];
// browser compatibility: attach event uses onmessage
var myEventMessage =
myEventMethod == "attachEvent" ? "onmessage" : "message";
// register callback function on incoming message
myEventListener(myEventMessage, function (e) {
// we will get a string (better browser support) and validate
// if it is an int - set the height of the iframe #my-iframe-id
if (e.data === parseInt(e.data))
document.getElementById(''iframe'').height = e.data + "px";
}, false);
</script>
</body>
</html>
https://-b.com iframe content:
<!DOCTYPE html>
<html>
<head>
<title>Test Iframe Content</title>
<script type="text/javascript">
// all content including images has been loaded
window.onload = function() {
// post our message to the parent
window.parent.postMessage(
// get height of the content
document.body.scrollHeight
// set target domain
,"*"
)
};
</script>
</head>
<body>
<br/><br/><br/><br/><br/><br/><br/><br/><br/><br/>1
<br/><br/><br/><br/><br/><br/><br/><br/><br/><br/>2
<br/><br/><br/><br/><br/><br/><br/><br/><br/><br/>3
<br/><br/><br/><br/><br/><br/><br/><br/><br/><br/>4
<br/><br/><br/><br/><br/><br/><br/><br/><br/><br/>5
<br/><br/><br/><br/><br/><br/><br/><br/><br/><br/>6
</body>
</html>
Mesa de trabajo:
xcom http> ycom https WORK
xcom https> ycom https WORK
xcom http> ycom http WORK
xcom https> ycom http WORK