Wie ändere ich die Größe eines Iframes aus einer anderen Domain?
-Bearbeiten
Scrollen Sie nach unten, um einige Lösungen zu finden. Oder lesen Sie, wie Sie dies NICHT tun können: D.
Nach vielen Stunden Code-Hacking ist die Schlussfolgerung, dass auf alles im Iframe nicht zugegriffen werden kann, selbst auf die Bildlaufleisten, die auf meiner Domain gerendert werden. Ich habe viele Techniken ohne Erfolg ausprobiert.
Um Zeit zu sparen, gehen Sie nicht einmal diesen Weg, sondern verwenden Sie sendMessages für die domänenübergreifende Kommunikation. Es gibt Plug-Ins für HTML <5, die ich benutze. Ein schönes Beispiel finden Sie unten :)
In den letzten Tagen habe ich versucht, einen Iframe in eine Site zu integrieren. Dies ist eine kurzfristige Lösung, während sich die andere Seite entwickelt und eine API (kann Monate dauern ...). Und da dies eine kurzfristige Lösung ist, die wir gemacht haben, möchten wir easyXDM verwenden. Ich habe Zugriff auf die andere Domain, aber es ist schwierig genug, sie darum zu bitten Fügen Sie den p3p-Header so hinzu, wie er ist .....
3 iframes
Die naheliegendste Lösung, die ich gefunden habe, waren die 3 Iframes - aber es geht um Chrom und Safari, also kann ich das nicht verwenden.
offen in Chrom
http://css-tricks.com/examples/iFrameResize/crossdomain.php#frameId=frame-one&height=1179
Messen Sie die Bildlaufleisten
Ich habe einen anderen Beitrag darüber gefunden, wie man die Bildlaufhöhe verwendet, um die Größe des Formulars zu ändern. Theoretisch funktioniert es gut, aber ich konnte es mit der Bildlaufhöhe des Iframes nicht richtig anwenden.
document.body.scrollHeight
Das verwendet offensichtlich die Körperhöhe (kann nicht zu 100% auf diese Eigenschaften zugreifen, basiert auf der Anzeige von canvaz des Clients und nicht auf der Höhe des X-Domains-Dokuments).
Ich habe versucht, mit jquery die Höhe des Iframes zu ermitteln
$('#frameId').Height()
$('#frameId').clientHeight
$('#frameId').scrollHeight
Rückgabewerte, die sich in Chrom und dh unterscheiden - oder überhaupt keinen Sinn ergeben. Das Problem ist, dass alles im Rahmen verweigert wird - sogar die Bildlaufleiste ...
Berechnete Stile
Aber wenn ich den Iframe inspiziere und in Chrom verteile, zeigt mir bladdy die Dokumentabmessungen innerhalb des Iframes (unter Verwendung der jquery x-domain, um iframe.heigh zu erhalten - Zugriff verweigert). Das berechnete CSS enthält nichts
Wie berechnet Chrom das? (Der Bearbeitungsbrowser rendert die Seite mithilfe der integrierten Rendering-Engine neu, um alle diese Einstellungen zu berechnen. Sie werden jedoch nirgendwo angehängt, um domänenübergreifenden Betrug zu verhindern. Also.)
HTML4
Ich habe die Spezifikation von HTML4.x gelesen und dort steht, dass schreibgeschützte Werte über document.element verfügbar gemacht werden sollen, der Zugriff jedoch über jquery verweigert wird
Proxy-Frame
Ich bin den Weg gegangen, die Site zurückzusenden und zu berechnen, was in Ordnung ist. Bis sich ein Benutzer über den Iframe anmeldet und der Proxy anstelle des eigentlichen Inhalts eine Anmeldeseite erhält. Auch für manche ist es nicht akzeptabel, die Seite zweimal aufzurufen
http://www.codeproject.com/KB/aspnet/asproxy.aspx
http://www.johnchapman.name/aspnet-proxy-page-cross-domain-requests-from-ajax-and-javascript/
Rendern Sie die Seite erneut
Ich bin nicht so weit gegangen, aber es gibt JScript-Engines, die sich die Quelle ansehen und die Seite basierend auf der Quelldatei neu rendern. Aber es würde das Hacken dieser JSkripte erfordern ... und das ist keine ideale Situation für kommerzielle Einheiten ... und einige greifen reine Java-Applets oder serverseitiges Rendering ein
http://en.wikipedia.org/wiki/Server-side_JavaScript
http://htmlunit.sourceforge.net/ <-java nicht jscript
EDIT 09-2013 UPDATE
All dies kann mit HTML5-Sockets durchgeführt werden. EasyXDM ist jedoch ein großartiger Fallback für Nicht-HTML5-Beschwerdeseiten.
Lösung 1 Sehr gute Lösung!
Mit easyXDM
Auf Ihrem Server richten Sie eine Seite in Form von ein
<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>
und in der Anruferdomäne müssen sie nur die HTML-Dateien intermiedate_frame und easyXDM.js an derselben Stelle hinzufügen. Wie ein übergeordneter Ordner - dann können Sie nur für Sie auf relative Verzeichnisse oder einen enthaltenen Ordner zugreifen.
OPTION 1
Wenn Sie nicht allen Seiten Skripte hinzufügen möchten, sehen Sie sich Option 2 an!
Dann können sie einfach ein einfaches jscript am Ende jeder Seite hinzufügen, für die die Größenänderung erforderlich ist. Das easyxdm muss nicht in jede dieser Seiten aufgenommen werden.
<script type="text/javascript">
window.onload = function(){ parent.socket.postMessage( (parseInt(document.body.clientHeight)) + "," + ( document.body.clientWidth ) ); };
</script>
Ich habe die gesendeten Parameter geändert. Wenn die Breite ordnungsgemäß funktionieren soll, müssen die Seiten in der anderen Domäne die Breite der Seite in einem Stil enthalten, der ungefähr so aussieht wie:
<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>
Das funktioniert gut für mich. Wenn die Breite nicht enthalten ist, verhält sich der Rahmen etwas seltsam und versucht zu erraten, was er sein soll. Er wird nicht verkleinert, wenn Sie es brauchen.
OPTION 2
Ändern Sie den Zwischenrahmen, um nach Änderungen zu suchen
Ihr Zwischenrahmen sollte ungefähr so aussehen.
<!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>
Das Intervall könnte effizienter gestaltet werden, um zu überprüfen, ob sich die Größe geändert hat, und nur dann zu senden, wenn sich die Abmessungen ändern, anstatt alle 500 ms Nachrichten zu veröffentlichen. Wenn Sie diese Prüfung durchführen, können Sie die Abfrage auf nur 50 ms ändern! habe Spaß
Arbeiten Sie browserübergreifend und schnell. Tolle Debugging-Funktionen !!
Excellent Work to Sean Kinsey who made the script!!!
Lösung 2 (funktioniert aber nicht so gut)
Wenn Sie also eine gegenseitige Vereinbarung mit der anderen Domain haben, können Sie eine Bibliothek hinzufügen, um sendmessage zu verarbeiten. Wenn Sie keinen Zugriff auf die andere Domain haben, suchen Sie weiter nach weiteren Hacks, da ich diese gefunden oder nicht vollständig rechtfertigen konnte.
Die andere Domain wird diese also in das Head-Tag aufnehmen
<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>
In der club.js sind nur einige benutzerdefinierte Anrufe, die ich für Größenänderungsanrufe getätigt habe und enthält ..
$(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 );
});
Und Ihre Seite wird die ganze harte Arbeit erledigen und hat ein schönes Skript ...
//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');
});
OPTION 3
Es handelt sich jetzt um eine kleine JS-Bibliothek zum Verwalten der Größenänderung domänenübergreifender iFrames. Der iFrame muss weiterhin über etwas JavaScript verfügen. Dies sind jedoch nur 2,8 KB (765 Byte Gzipped) nativer JS, die keine Abhängigkeiten aufweisen und es macht nichts, bis es von der übergeordneten Seite aufgerufen wird. Dies bedeutet, dass es ein netter Gast auf anderen Personensystemen ist.
Dieser Code verwendet mutationsObserver, um DOM-Änderungen zu erkennen, und sucht auch nach Größenänderungsereignissen, damit der iFrame an den Inhalt angepasst bleibt. Funktioniert in IE8 +.
Antworten:
Die Sache ist - es gibt keinen anderen Weg als die Verwendung von domänenübergreifendem Messaging, da Sie die berechnete Höhe von einem Dokument in einer Domäne zu einem Dokument in einer anderen Domäne abrufen müssen.
Entweder tun Sie dies mit
postMessage
(funktioniert in allen moderaten Browsern) oder Sie verbringen 5 Minuten damit, das Beispiel für die Größenänderung des Iframes von easyXDM anzupassen.Die andere Partei muss wirklich nur ein paar Dateien in ihre Domain kopieren und ihrem Dokument eine einzige Codezeile hinzufügen.
quelle
Ähnlich wie Sean es erwähnt hat, können Sie postMessage verwenden. Ich habe so viel Zeit damit verbracht, verschiedene Methoden auszuprobieren, um die Größe des Iframes domänenübergreifend zu ändern, aber kein Glück, bis ich auf diesen großartigen Blog-Beitrag von David Walsh gestoßen bin: http://davidwalsh.name/window-iframe
Dies ist eine Kombination aus meinem Code und Davids Lösung. Meine Lösung ist speziell auf die Größenänderung von Iframes ausgerichtet.
Suchen Sie auf der untergeordneten Seite die Höhe der Seite und übergeben Sie sie an die übergeordnete Seite (die den Iframe enthält). Ersetzen Sie element_id durch Ihre Element-ID (HTML, Body, was auch immer).
Fügen Sie im übergeordneten Fenster diesen Code hinzu. Ersetzen Sie iframe_id durch Ihre iframe-ID:
Wenn Sie die Konsole öffnen, wird die Höhe im Konsolenprotokoll angezeigt. Dies wird Ihnen beim Debuggen helfen, weshalb ich es dort gelassen habe.
Am besten, Baker
quelle
Nachdem ich viele verschiedene Lösungen dafür gesucht hatte, schrieb ich eine einfache kleine Bibliothek, um eine Reihe verschiedener Anwendungsfälle zu berücksichtigen. Da ich eine Lösung benötigte, die mehrere benutzergenerierte iFrames auf einer Portalseite unterstützte, änderte der unterstützte Browser die Größe und konnte das Laden von JavaScript auf der Hostseite nach dem iFrame bewältigen. Ich füge auch Unterstützung für die Größenanpassung auf Breite und eine Rückruffunktion hinzu und erlaube das Überschreiben der body.margin, da Sie diese wahrscheinlich auf Null setzen möchten.
https://github.com/davidjbradshaw/iframe-resizer
Der Iframe-Code ist nur ein kleines, in sich geschlossenes JavaScript, sodass er auf anderen Personenseiten ein guter Gast ist.
Das Skript wird dann auf der Hostseite mit den folgenden verfügbaren Optionen initialisiert.
quelle
Anstatt scroll = no für den Iframe zu verwenden, ändere ich ihn auf "auto". Dann bekomme ich die Größe des tatsächlichen Fensters
und verwenden Sie dies als iframe height-Attribut.
Nun, das Ergebnis ist ...
Wir werden niemals die Schriftrolle "Seite" haben, sondern nur die Schriftrolle "Iframe". Wenn Sie navigieren, spielt es keine Rolle, wer die Schriftrolle ist, aber wichtig ist, dass es nur 1 gibt.
Nun, es gibt das Problem, dass der Benutzer einfach die Größe des Fensters ändert, während er navigiert. Um das zu lösen, benutze ich:
Haben Sie gedacht, dass diese Lösung Fehler verursachen wird? Es funktioniert für mich und auf dem iFrame hatte ich einen dynamischen Kontakt, der von PHP generiert wurde. Ich habe Angst vor zukünftigen Fehlern damit ...
quelle
Heutzutage gibt es nur 4 Lösungen, die ich kenne:
Nur der dritte kann viele Probleme lösen. Zum Beispiel können Sie ansprechende iFrame erstellen ; Schließen Sie es von innen oder Sie können mit ihm kommunizieren . Dazu benötigen Sie jedoch iFrame in Iframe und die Problemumgehung "Cookies von Drittanbietern" (optional).
Ich habe einen Artikel darüber mit Beispiel erstellt: Ereignisgesteuerter domänenübergreifender iFrame
quelle
Haben Sie sich die HTML5-Attribute "Objektanpassung" angesehen? Skaliert Videos / Bilder auf den Iframe, anstatt den Iframe zu skalieren (schön, wenn Sie ein mittelgroßes Bild mit einer Breite von 5.000 Pixel aufnehmen). Die Option "Anpassen" (andere sind "Cover" und "Füllen") verwendet einen Briefkasten-Ansatz, um die Quelle unter Beibehaltung der Seitenverhältnisse anzupassen. Für die Anzeige mit HTML5-weniger da draußen sieht es so aus, als ob eine ganze Menge Polyfills verfügbar sind. Dieser ist großartig, aber ein Fehler am Ende von Edge hat ihn seit etwa einem Jahr mit Microsoft New Nightmare inkompatibel gemacht: https://github.com/anselmh/object-fit
BEARBEITEN: Um domänenübergreifende Probleme zu umgehen, können Sie die Arbeit immer nur in einem Chrome Extension Content Script ausführen, da es denkt, dass es Teil der Seite ist, auf die Sie Ihren Iframe kleben.
quelle
HTTPS Ein anderer Link erhält die Höhe zur Autohöhe des Iframes
https://-a.com Inhalt:
https://-b.com iframe-Inhalt:
Arbeitstisch:
xcom http> ycom https ARBEITEN
xcom https> ycom https ARBEITEN
xcom http> ycom http ARBEITEN
xcom https> ycom http ARBEITEN
quelle
Suchen Sie nach der Höhe der Seite, die im iframe enthalten ist? Ich habe Javascript zum Laufen gebracht, das die Höhe des Iframe-Inhalts überprüft und dann die Höhe des Iframes auf die Höhe des Inhalts setzt.
Dies funktioniert jedoch nur, wenn sich die Seite, die Sie im Iframe anzeigen, in derselben Domäne befindet. Ist dies nicht der Fall, können Sie nicht auf die erforderlichen Informationen zugreifen. Daher verweigerte der Zugriff den Fehler.
quelle
Um die Größe eines Iframes zu ändern, ist hier ein einfaches Skript:
Das geht in den Kopf: (Dies wurde für ein PHP-Skript geschrieben, für HTML ändern Sie das 'in "und das \" in' ...
Kopfende
Dies geht in den Körper (denken Sie daran, dies wurde für ein PHP-Skript geschrieben, für HTML ändern Sie alle 'zu "und die \" zu' ...)
Bonus: Es gibt einige Hinweise oben. Da es für PHP-Scripting eingestellt ist, können Sie viel damit anfangen ... um mehr zu lernen, mehr zu tun ...
Der Schlüssel dazu ist "sizeframe1". Kopieren Sie für mehrere "Resizer" auf derselben Seite dasselbe Skript, ändern Sie jedoch die ID in iframe und den Namen im Skript im Kopf und die Bratsche! Sie haben mehrere Resizer auf derselben Seite ... es funktioniert sehr gut!
habe phun.
quelle