Signatur
Beschreibung
Die Eigenschaft srcdoc spiegelt das gleichnamige HTML-Attribut eines <iframe>-Elements wider. Statt über src eine URL zu laden, übergibt man den HTML-Quelltext des einzubettenden Dokuments direkt als String. Der Browser erzeugt daraus ein vollständiges Dokument mit der URL about:srcdoc.
Typische Einsatzfälle sind Live-Vorschauen in Editoren (z. B. HTML/CSS-Playgrounds, E-Mail-Vorschauen, CMS-Vorschauen), das isolierte Darstellen von Fremd-HTML zusammen mit dem Attribut sandbox und das Erzeugen kleiner Hilfsdokumente, ohne dafür eine eigene Datei, einen Server-Endpunkt oder eine blob:-URL anlegen zu müssen.
Wichtig: Ist srcdoc gesetzt, hat es Vorrang vor src. Jede Zuweisung lädt den Frame neu (das Ereignis load wird erneut ausgelöst). Ohne sandbox erbt das srcdoc-Dokument den Ursprung (Origin) des einbettenden Dokuments – Skripte darin haben also vollen Zugriff auf die Elternseite. Mit sandbox (ohne allow-same-origin) erhält es dagegen einen undurchsichtigen, eigenen Ursprung.
Beim Lesen wird der aktuelle Attributwert als String zurückgegeben – nicht das eventuell per Skript veränderte DOM des Frames. Dafür nutzt man iframe.contentDocument.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $value Pflicht | string | TrustedHTML | "" | Beim Setzen: vollständiger oder teilweiser HTML-Quelltext des Frame-Dokuments. Fehlen <html>, <head> oder <body>, ergänzt der Parser sie automatisch. Bei aktiven Trusted Types muss ein TrustedHTML-Objekt übergeben werden. |
Rückgabewert
srcdoc. Ist das Attribut nicht gesetzt, ein leerer String "".Beispiele
Einfache Inline-Vorschau erzeugen
const iframe = document.createElement('iframe');
iframe.srcdoc = `
<!doctype html>
<style>body { font-family: sans-serif; color: #333; }</style>
<h1>Hallo aus dem Frame</h1>
<p>Dieses Dokument existiert nur als String.</p>
`;
document.body.append(iframe);
iframe.addEventListener('load', () => {
console.log(iframe.contentWindow.location.href);
console.log(iframe.contentDocument.querySelector('h1').textContent);
});
Live-Vorschau für einen HTML-Editor (sandboxed)
const editor = document.querySelector('#editor'); // <textarea id="editor">
const preview = document.querySelector('#preview'); // <iframe id="preview">
// Skripte erlauben, aber keinen Zugriff auf die Elternseite
preview.sandbox = 'allow-scripts';
let timer;
editor.addEventListener('input', () => {
clearTimeout(timer);
// Entprellen, damit nicht bei jedem Tastendruck neu geladen wird
timer = setTimeout(() => {
preview.srcdoc = editor.value;
}, 300);
});
Wert auslesen und src-Vorrang prüfen
const frame = document.createElement('iframe');
frame.src = 'https://example.com/';
frame.srcdoc = '<p>Ich gewinne gegen src.</p>';
document.body.append(frame);
console.log(frame.srcdoc);
console.log(frame.getAttribute('srcdoc') === frame.srcdoc);
// Attribut entfernen -> Frame lädt jetzt die src-URL
frame.removeAttribute('srcdoc');
console.log(JSON.stringify(frame.srcdoc));
Nachrichten mit einem sandboxed srcdoc-Frame austauschen
const frame = document.createElement('iframe');
frame.sandbox = 'allow-scripts';
frame.srcdoc = `
<script>
window.addEventListener('message', (e) => {
e.source.postMessage('Antwort: ' + e.data.toUpperCase(), '*');
});
<\/script>
`;
document.body.append(frame);
window.addEventListener('message', (e) => {
if (e.source === frame.contentWindow) console.log(e.data);
});
frame.addEventListener('load', () => {
// Sandboxed Frame hat Origin "null" -> Ziel '*' nötig
frame.contentWindow.postMessage('hallo', '*');
});
// Wichtig · Fallstricke
- Sicherheit (XSS):
srcdocohnesandboxläuft mit dem Ursprung der Elternseite. Wer Benutzer- oder Fremd-HTML ungefiltert zuweist, öffnet genauso eine XSS-Lücke wie beiinnerHTML– Skripte im Frame können überparentCookies,localStorageund DOM der Hauptseite lesen. Für nicht vertrauenswürdige Inhalte immersandboxsetzen und niemalsallow-scriptszusammen mitallow-same-originkombinieren, da sich der Frame sonst selbst aus der Sandbox befreien kann. - Trusted Types / CSP:
srcdocist eine Injektionssenke. Beirequire-trusted-types-for 'script'wirft eine String-Zuweisung einenTypeError; es muss einTrustedHTMLübergeben werden. Ohne Sandbox erbt das Frame-Dokument außerdem die Content Security Policy der Elternseite. - Vorrang: Ist
srcdocvorhanden, wirdsrcignoriert. Erst nachremoveAttribute('srcdoc')greift wiedersrc(srcdoc = ''reicht nicht, da das Attribut dann weiter existiert). - Neu laden: Jede Zuweisung verwirft das bisherige Dokument inkl. Zustand und Scrollposition. Bei Live-Vorschauen entprellen oder alternativ direkt über
contentDocumentaktualisieren. - Relative URLs im
srcdoc-Inhalt werden gegen die Basis-URL der Elternseite aufgelöst; ein eigenes<base href>im Markup ändert das. - Escaping im HTML-Attribut: Im Markup müssen Anführungszeichen und
&als Entitäten kodiert werden. Über die JS-Eigenschaft entfällt das. In Template-Strings innerhalb eines<script>-Blocks muss</script>maskiert werden (z. B.<\/script>). - Kompatibilität: Wird von allen modernen Browsern unterstützt (Chrome, Firefox, Safari, Chromium-Edge), jedoch nicht vom Internet Explorer und vom alten EdgeHTML-Edge. Als Fallback dienen dort
blob:- oderdata:-URLs übersrc.