JavaScript/Tutorials/Fenster- und Frameszugriff
In Javascript gibt es das window-Objekt als oberste Instanz über allen anderen Objekten. Es bietet die Methode window.open()
zum Öffnen neuer Fenster an (und außerdem alle weiteren Unterobjekte, Eigenschaften und Methoden, die in der Javascript-Objektreferenz aufgelistet sind).[1]
In JavaScript kannst du mit verschiedenen Browserfenstern, Tabs und Frames (wie iframes) arbeiten, indem du das Window-Objekt verwendest. Dies ist nützlich, um Folgendes zu tun:
- Popup-Fenster öffnen und mit ihnen kommunizieren
- andere Webseiten, Widgets oder aktive Inhalte wie Karten, Videos, etc. in einem iframe einbetten
- Nachrichten zwischen Fenstern oder Frames weitergeben
Dies ist auch heute (2025) noch möglich, aber durch moderne Sicherheitsmechanismen wie Cross-Origin Restrictions (CORS, Same-Origin-Policy), Popup-Blocker und striktere Browserrichtlinien eingeschränkt.
Inhaltsverzeichnis
Popover im neuen Fenster
Fenster in JavaScript sind hierarchisch aufgebaut – sie bilden eine Baumstruktur. Jedes Fenster kennt dabei bestimmte verwandte Fensterobjekte:
-
top
verweist auf das oberste Fenster der Hierarchie. Ist man bereits ganz oben, zeigt top auf sich selbst. -
parent
zeigt auf das direkt übergeordnete Fenster – oder auf sich selbst, wenn es kein übergeordnetes gibt. -
self
ist das aktuelle Fenster (und kann meist weggelassen werden). -
opener
verweist auf das neue Fenster, das mit window.open() geöffnet wurde – oder ist null, wenn es kein solches gibt.
Mit diesen Eigenschaften kann man gezielt innerhalb verschachtelter Fenster oder eingebetteter Inhalte navigieren.
Ein neues Fenster
Mit Window.open() ist es möglich ein neues „Fenster“ zu öffnen. Dabei haben sich in den letzten Jahren einige Änderungen ergeben: Browser öffnen neue Fenster heute im allgemeinen nicht mehr in einem neuen Fenster oberhalb des aktuellen Fensters, sondern in einer neuen Registerkarte - einem Tab.
Ein Spaß der 90er, einem unbedarftem Nutzer eine Endlosschleife sich selbst öffnender Fenster zu schicken, ist heute so unmöglich:
setTimeout(() => { window.open("seite.html"); }, 1000);
Browser wie Chrome, Firefox oder Safari blockieren window.open()
wenn es nicht direkt durch eine Benutzeraktion ausgelöst wurde (z. B. durch ein Click-Event).
function fensterOeffnen() {
window.open('https://forum.selfhtml.org/');
}
Durch einen Klick auf den Button wird die Funktion fensterOeffnen()
aufgerufen, die mit window.open()
ein neues Fenster in einer neuen Registerkarte öffnet.
Im Normalfall wird nur eine neue Registerkarte geöffnet.
iframes - „Fenster im Fenster“?
Ein iframe ist wie ein kleines Fenster innerhalb einer Webseite.
- Es zeigt eine eigene Webseite innerhalb einer anderen Webseite.
- Es hat einen eigenen DOM-Baum, eine eigene window-Instanz und einen eigenen JavaScript-Kontext.
Dadurch wirkt es tatsächlich wie ein „eingebettetes Fenster“ im Browserfenster.
Allerdings ist ein echtes Browserfenster (z. B. durch window.open()
) unabhängig vom Hauptfenster.
Auch vom Sicherheitsmodell (Same-Origin-Policy) wird ein iframe strenger behandelt als z. B. ein selbst geöffnetes Fenster.
iframes passend dimensionieren
Im SELF-Forum wird häufig gefragt, wie man die Dimensionen der eingebundenen Inhalte ermitteln kann, um dann den iframe entsprechend anzupassen, damit alle Inhalte angezeigt werden und keine Scrollbalken erscheinen.
(Die Default-Stylesheets verwenden 300 x 150px
!)
Zuerst schaffen wir eine Demo-Seite mit wechselnder Höhe:
function changeHeight() {
const content = document.getElementById("content");
const output = document.getElementById("output");
const newHeight = rand(1,20);
content.style.height = newHeight + "em";
output.textContent = "Höhe: " + newHeight + "em";
}
Dem HTML-Element mit der id content
wird über eine Zufallsfunktion rand(min, max)
eine wechselnde Höhe newHeight
zugewiesen. Im div befindet sich ein output-Element, dass die jeweilige Höhe anzeigt.
Diese Webseite wird nun in unser Beispiel eingebunden:
<iframe
id="myFrame"
src="Iframe-embedded-1.html">
</iframe>
Mit JavaScript wird nun das eingebettete Elemente aufgerufen:
const iframe = document.getElementById('myFrame');
iframe.addEventListener('load', () => {
const iframeDocument = iframe.contentDocument || iframe.contentWindow.document;
const iframeBody = iframeDocument.body;
const observer = new ResizeObserver(entries => {
for (const entry of entries) {
const height = entry.contentRect.height;
iframe.style.height = (height + 36) + 'px';
}
});
observer.observe(iframeBody);
});
Der iframe wird über seine id identifiziert und ein EventListener angehängt, der das load-Event überwacht.
Sobald dies erfolgt ist, wird mit einem ResizeObserver auf Höhenänderungen reagiert, indem die Höhe des iframes über style.height
angepasst wird.
Von Fenster zu Fenster reden
Wenn die untergeordnete Seite des iframe nicht denselben Ursprung hat (d. h. andere Domain, Subdomain, Port oder Protokoll), dann kann die Elternseite aufgrund der Same-Origin-Policy des Browsers nicht direkt auf das DOM des Kinds zugreifen.
In diesem Fall muss das Kind die Höhe bereits ermitteln und mittels postMessage an die Elternseite melden.
const observer = new ResizeObserver(entries => {
for (const entry of entries) {
const height = Math.round(entry.contentRect.height);
window.parent.postMessage(
{ type: 'resize', height: height },
"https://wiki.selfhtml.org/"
);
}
});
Die Child-Seite erhält wieder einen ResizeObserver, der die Höhe ermittelt und sie dann an window.parent
sendet.
postMessage hat zwei Parameter:
-
{ type: 'resize', height: height }
: Die zu übertragenden Daten. - der erwartete Origin der Elternseite. Für den Fall, dass der iframe-Inhalt von einer fremdem Seite eingebunden wird, lässt sich so verhindern, dass Daten gestohlen werden.
const iframe = document.getElementById('myFrame');
window.addEventListener('message', (event) => {
if (event.origin !== "https://wiki.selfhtml.org") return;
const data = event.data;
if (data?.type === 'resize' && typeof data?.height === 'number') {
iframe.style.height = (data.height) + 'px';
}
});
Sicherheit und Kontrolle
Framekiller-Strategien
Verhindern kann man das Einbinden der eigenen Webseite in ein Frameset durch JavaScript, ähnlich wie bei dem Adressierungsproblem. Derartige JavaScripte werden auch als Framekiller oder Framebuster bezeichnet.
<script>
if (top!=self) top.location.href=self.location.href;
</script>
Alternativ kann der Response Header Content-Security-Policy direkt im Webserver gesetzt werden. Mit der Direktive frame-ancestors lässt sich dabei steuern, ob und von wem eine Webseite in einem <frame> oder <iframe> eingebettet werden darf.
-
Content-Security-Policy: frame-ancestors 'none'
keine einbettung
-
Content-Security-Policy: frame-ancestors 'self'
nur Webseiten der same origin
Bei Shared Hostern, bei denen kein direkter Zugriff auf die Webserver-Konfiguration möglich ist, kann – sofern Apache als Webserver verwendet wird – der entsprechende Response Header auch über die .htaccess-Datei gesetzt werden, beispielsweise mit:
Header set Content-Security-Policy "frame-ancestors 'none'"
Weblinks
- ↑ Dieser Artikel ist eine Neubearbeitung eines Selfhtml-aktuell-Artikels von Sven Rautenberg, 29.07.2002
JavaScript: Fenster- und Frameszugriff –: Zugriff auf komplexe verschachtelte Fensterobjekte
Website mit COOP und COEP „ursprungsübergreifend isoliert“ machen (web.dev)
ToDo (weitere ToDos)
Dies ist der Versuch einer Neukonzeption.
Peer Review und weitere Ideen erbeten.
--Matthias Scharwies (Diskussion) 06:30, 26. Jun. 2025 (CEST)