[LEITFADEN] 10 min read

[LEITFADEN] Daten-URIs verstehen: data:image/png;base64,... erklärt

Ein praxisnaher Leitfaden zum data:-URI-Schema – was jeder Bestandteil von data:image/png;base64,iVBORw0KGgo... tatsächlich bedeutet, wann das Einbetten die richtige Wahl ist und wann es Sie zurückbeißt.

April 2026 | fundamentals

// WAS EIN data:-URI WIRKLICH IST

Ein data:-URI ist ein URI-Schema – wie https: oder file: –, das die Ressource selbst direkt in die URI-Zeichenkette einbettet, statt auf einen entfernten Speicherort zu verweisen. Definiert in RFC 2397, ermöglicht es Ihnen, einen kleinen Block aus Binär- oder Textdaten so zu behandeln, als wäre er eine URL.

Die häufigste Form, die Ihnen in der Praxis begegnet, betrifft Bilder: data:image/png;base64,iVBORw0KGgoAAAANSUhEUg.... Der Browser sieht diese URL, liest den MIME-Typ, dekodiert die Base64-Nutzlast zurück in Bytes und rendert das Bild – ganz ohne HTTP-Anfrage.

// DIE SYNTAX, STÜCK FÜR STÜCK

Die vollständige Syntax lautet data:[<mediatype>][;base64],<data>. Drei optionale Bestandteile und ein erforderliches Trennzeichen (das Komma). Zerlegen wir ein konkretes Beispiel:

Nehmen Sie data:image/png;base64,iVBORw0KGgoAAAANSUhEUg... und lesen Sie es von links nach rechts:
data: – das Schema. Teilt dem Parser mit: „Die Ressource befindet sich in der URL selbst, kein Abruf nötig.“
image/png – der MIME-Typ. Sagt dem Renderer, wie die Nutzlast zu interpretieren ist. Standard ist text/plain;charset=US-ASCII, falls weggelassen.
;base64 – Kennzeichnung der Kodierung. Gibt an, dass die Nutzlast Base64 (RFC 4648) ist. Ohne dieses Flag wird die Nutzlast als URL-kodierter Text interpretiert.
, – das erforderliche Trennzeichen zwischen Metadaten und Nutzlast.
iVBORw0KGgo... – die eigentlichen Base64-kodierten Bildbytes.

// Anatomy diagram
// data:image/png;base64,iVBORw0KGgoAAAANSUhEUg...
// │    │         │      │
// │    │         │      └── Base64 payload (the actual image bytes)
// │    │         └────────── encoding flag (always 'base64' for binary)
// │    └──────────────────── MIME type (optional, defaults to text/plain)
// └───────────────────────── scheme literal (always 'data:')

// WARUM ES data:-URIs GIBT

Drei Gründe, warum Entwickler statt regulärer Bild-URLs zu Daten-URIs greifen:

1. Eine HTTP-Anfrage einsparen. Jedes <img src="..."> auf einer Seite kostet einen Netzwerk-Roundtrip. Für ein winziges Symbol oder Sprite kann dieser Roundtrip länger dauern als die Übertragung der Bytes selbst. Das Einbetten des Bildes als Daten-URI bündelt es mit dem HTML/CSS und entfernt die Anfrage vollständig. Das war in der HTTP/1.1-Ära besonders wichtig; mit HTTP/2-Multiplexing fällt es weniger ins Gewicht, aber für kritische Symbole oberhalb der Bildkante hilft es weiterhin.

2. Den Asset eigenständig machen. Eine HTML-E-Mail muss in Clients gerendert werden, die externe Bilder standardmäßig blockieren (Gmail, Outlook). Ein statischer Bericht, den Sie an einen Kunden mailen, muss das Firmenlogo auch offline anzeigen. Ein Bookmarklet braucht ein Symbol, das Copy-and-Paste übersteht. Ein Dokumentations-Snippet braucht einen Screenshot, der zusammen mit dem Markdown reist. In all diesen Fällen muss das Bild innerhalb des Dokuments leben – und ein Daten-URI ist genau dafür da.

3. Programmatische Erzeugung. Code erzeugt zur Laufzeit ein Bild – einen QR-Code, ein Diagramm, eine Unterschriftsfläche – und Sie müssen es anzeigen, ohne es zuerst auf einen Server hochzuladen und eine URL zurückzubekommen. canvas.toDataURL('image/png') liefert Ihnen direkt einen Daten-URI; ihn an img.src zuzuweisen ist der einfachste denkbare Workflow.

// JEDER MIME-TYP, DEN SIE TATSÄCHLICH SEHEN WERDEN

Der MIME-Typ-Slot akzeptiert jeden Medientyp, in der Praxis sehen Sie aber nur eine kleine Handvoll bei Bildern:

image/png – am häufigsten. Verlustfrei, mit Transparenz. Base64 beginnt mit iVBORw0KGgo.
image/jpeg – Fotos und Screenshots. Verlustbehaftet. Base64 beginnt mit /9j/.
image/gif – legacy und animierte Bilder. Base64 beginnt mit R0lGOD.
image/webp – modern, kleinere Dateien. Base64 beginnt mit UklGR.
image/svg+xml – Vektorgrafiken. SVG ist Text, daher können Sie es entweder Base64-kodieren (mit ;base64) oder URL-kodieren (ohne). URL-kodiertes SVG ist meist kleiner.
image/x-icon oder image/vnd.microsoft.icon – Favicons. Base64 beginnt mit AAABAA.

<!-- All five types in a single HTML document -->
<img src="data:image/png;base64,iVBORw0KGgo..." alt="PNG inline">
<img src="data:image/jpeg;base64,/9j/4AAQSkZJRg..." alt="JPEG inline">
<img src="data:image/gif;base64,R0lGODlhAQABAA..." alt="GIF inline">
<img src="data:image/webp;base64,UklGRiIAAABXRU..." alt="WebP inline">
<img src="data:image/svg+xml;base64,PHN2ZyB4bWxu..." alt="SVG inline">

// data:-URIs IN HTML, CSS UND JAVASCRIPT VERWENDEN

Überall, wo eine URL akzeptiert wird, funktioniert auch ein Daten-URI auf dieselbe Weise.

<!-- HTML <img> tag -->
<img src="data:image/png;base64,iVBORw0KGgo..." width="32" height="32" alt="icon">

<!-- HTML <link> for favicon -->
<link rel="icon" href="data:image/x-icon;base64,AAABAAEAEBA...">

/* CSS background-image */
.button-icon {
  background-image: url('data:image/svg+xml;base64,PHN2ZyB4bWxu...');
  background-size: 16px 16px;
}

/* CSS @font-face — yes, fonts work too */
@font-face {
  font-family: 'InlineFont';
  src: url('data:font/woff2;base64,d09GMgAB...') format('woff2');
}

// JavaScript — assign directly to img.src
const img = new Image();
img.src = 'data:image/png;base64,iVBORw0KGgo...';
document.body.appendChild(img);

// JavaScript — fetch a data URI like any other URL
const response = await fetch('data:application/json;base64,eyJrZXkiOiJ2YWx1ZSJ9');
const data = await response.json(); // { key: 'value' }

// CANVAS, FILE UND BLOB → data:-URI

Drei Browser-APIs liefern Ihnen einen Daten-URI, ohne dass Sie die Base64-Kodierung selbst durchführen müssen:

// 1. Canvas → data URI (instant)
const canvas = document.querySelector('canvas');
const pngDataURI = canvas.toDataURL('image/png');
const jpegDataURI = canvas.toDataURL('image/jpeg', 0.85); // quality 0–1
// pngDataURI === 'data:image/png;base64,iVBORw0KGgo...'

// 2. <input type="file"> → data URI via FileReader
const file = document.querySelector('input[type=file]').files[0];
const reader = new FileReader();
reader.onload = () => {
  // reader.result is the data URI
  document.querySelector('img').src = reader.result;
};
reader.readAsDataURL(file);

// 3. Blob → data URI (manual, but rarely needed — use URL.createObjectURL instead)
const blob = new Blob([bytes], { type: 'image/png' });
const reader2 = new FileReader();
reader2.onload = () => console.log(reader2.result);
reader2.readAsDataURL(blob);
// Or, for in-page display, prefer:
const objectURL = URL.createObjectURL(blob); // 'blob:https://...' — much shorter, no Base64

// DER 33-PROZENT-GRÖSSENZUSCHLAG (UND WANN ER WICHTIG IST)

Base64 verwandelt 3 Bytes Binärdaten in 4 ASCII-Zeichen, sodass die kodierte Nutzlast exakt 4⌈n/3⌉ Bytes beträgt – also rund 33 Prozent größer als das Original. Aus einem 12-KB-PNG wird ein etwa 16 KB großer Daten-URI, plus ein paar Bytes Overhead für das Präfix data:image/png;base64,.

Wann spielt das eine Rolle?
Winzige Assets (unter 4 KB): Der 33-prozentige Aufschlag wird durch den eingesparten HTTP-Roundtrip in den Schatten gestellt. Großzügig einbetten.
Mittlere Assets (4–50 KB): Fall für Fall entscheiden. Mit HTTP/2 + Caching ist eine separate Anfrage meist schneller, als die eingebettete Version bei jedem Seitenaufruf erneut herunterzuladen.
Große Assets (50 KB+): Fast nie einbetten. Der Daten-URI bläht jede gecachte HTML-Seite, jede E-Mail und jede JSON-Nutzlast auf, die ihn enthält. Verwenden Sie eine separate URL.

Für Daten-URIs gibt es kein Caching – der Browser kann ein Bild, dessen Bytes ins HTML einbacken sind, nicht zwischenspeichern. Erscheint dasselbe Bild auf mehreren Seiten, zahlt jede Seite die volle Last. Ein reguläres <img src="/logo.png"> mit HTTP-Cache-Headern wird einmal geladen und überall wiederverwendet.

// BROWSER-LIMITS, AUF DIE SIE STOSSEN WERDEN

Browser legen kein einheitliches hartes Limit für Daten-URIs fest, aber in der Praxis gibt es Obergrenzen:

Chrome / Edge / Firefox: Daten-URIs in <img src> funktionieren bis zu mehreren Megabyte. Jenseits von etwa 32 MB stoßen Sie auf Speicherdruck pro Tab.
Safari: begrenzte Daten-URIs in <a href> (Download-Links) historisch auf rund 2 MB. Für <img> funktionieren größere Werte, das Rendering wird jedoch langsamer.
Internet Explorer 8: maximal 32 KB für Daten-URIs in CSS und HTML. (IE9+ hat das Limit entfernt, war aber nie so schnell wie moderne Browser.)
HTTP-Anfragezeile: Daten-URIs in <form action> oder Query-Strings sind durch die vom Browser akzeptierte URL-Länge begrenzt (~2 KB für IE, 8 KB+ für andere).

Wenn Sie an eines dieser Limits stoßen, ist der Asset zu groß zum Einbetten. Wechseln Sie auf eine reguläre URL oder auf URL.createObjectURL(blob), das Ihnen eine kurze blob:-URL liefert, die durch ein im Speicher gehaltenes Blob gestützt wird.

// SICHERHEITSASPEKTE

Daten-URIs sind netzwerkfrei, was praktisch ist – aber sie umgehen mehrere Web-Sicherheitsmechanismen, die davon ausgehen, dass Inhalte vom Server stammen.

Same-Origin-Policy. Ein data:-URI gilt technisch als opaker Ursprung (in modernen Versionen von Chrome und Firefox), sodass JavaScript, das aus einem Daten-URI geladen wurde, nicht uneingeschränkt auf Cookies, localStorage oder das DOM des übergeordneten Dokuments zugreifen kann. Das ist gut für das Sandboxing nicht vertrauenswürdiger Inhalte, bedeutet aber auch, dass Tracking, Analytics und CSRF-Schutzmaßnahmen, die auf Origin-Prüfungen beruhen, fehlerhaft funktionieren können.

XSS via data:text/html. Eine vom Benutzer ausgeführte URL wie data:text/html,<script>...</script> wird zu einer voll privilegierten Seite. Moderne Browser blockieren aus diesem Grund die Top-Level-Navigation zu data:text/html (Firefox seit 2018, Chrome seit 2020). Geben Sie keine vom Benutzer gelieferten URLs durch eine Weiterleitung weiter, die das data:-Schema zulässt.

Content Security Policy (CSP). Standardmäßig blockieren strenge CSPs Daten-URIs in img-src, style-src usw. Um sie zuzulassen, müssen Sie data: explizit in die Direktive aufnehmen (z. B. img-src 'self' data:). Treffen Sie diese Entscheidung bewusst – sobald Sie Daten-URIs erlauben, akzeptieren Sie auch jedes Bild (oder jede Schriftart), das die Seite einbettet.

Logging und PII. Ein Daten-URI ist Teil der URL. Jeder Logger oder jedes Analyse-Werkzeug, das URLs erfasst (Server-Zugriffsprotokolle, Browser-Verlauf, Fehler-Tracker), erfasst die gesamte Nutzlast. Enthält Ihr Daten-URI das Avatarbild, ein Foto oder einen Screenshot eines Nutzers, landet er in Ihren Logs. Geben Sie keine PII in URLs, die Sie nicht kontrollieren.

// data:-URI vs. blob:-URL – WELCHE SOLLTEN SIE VERWENDEN?

Mit beiden lassen sich Binärdaten aus dem Speicher anzeigen, ohne sie hochzuladen. Die Wahl hängt davon ab, wo die Daten leben müssen.

Verwenden Sie data:-URI, wenn die Daten portabel sein müssen – eingebettet in HTML, in JSON versendet, in einer Datenbank gespeichert, per Copy-and-Paste in eine E-Mail kopiert. Die Daten sind die URL.

Verwenden Sie blob:-URL, wenn die Daten lokal und kurzlebig sind – eine Vorschau in einer Single-Page-App, ein Download-Trigger, ein Bild, das beim Schließen der Seite verschwindet. URL.createObjectURL(blob) liefert Ihnen eine kurze Kennung (blob:https://example.com/12345-abcde), die der Browser auf das Blob im Speicher zurückabbildet. Deutlich kleiner als ein Daten-URI, und Sie können sie mit URL.revokeObjectURL(url) widerrufen, sobald Sie fertig sind.

Faustregel: Muss die URL die aktuelle Seite verlassen, verwenden Sie data:. Bleibt sie innerhalb der Seite, verwenden Sie blob:.

// HÄUFIGE DEBUG-PROBLEME

Abgeschnittene Zeichenkette in den DevTools. Wenn Sie einen langen Daten-URI aus dem Network-Tab oder dem Elements-Panel kopieren, kürzen Browser den Wert oft mit einem Auslassungszeichen. Der angezeigte Text ist nicht die vollständige URL. Um die vollständige Zeichenkette zu erhalten, öffnen Sie die Quelldatei (CSS, HTML, JSON) direkt oder verwenden Sie in der Konsole document.querySelector('img').src – das liefert die vollständige URL zurück.

Falscher MIME-Typ. Eine PNG-Nutzlast, die als data:image/jpeg;base64,... beschriftet ist, wird auf Byte-Ebene trotzdem dekodiert – Base64 schert sich nicht um MIME –, aber einige Viewer lehnen die Diskrepanz ab. Das tatsächliche Format wird durch die magischen Bytes bestimmt (iVBORw0KGgo für PNG); im Zweifel fügen Sie die Nutzlast in unseren Base64-zu-Bild-Decoder ein – er erkennt das Format automatisch anhand der Bytes.

Fehlendes Komma. Das Format lautet data:image/png;base64,iVBORw..., nicht data:image/png;base64;iVBORw.... Ein Semikolon oder ein fehlendes Trennzeichen macht die gesamte URL ungültig.

URL-sicheres Base64 in einem data:-URI. Standardmäßige data:-URIs verwenden das Standard-Base64-Alphabet (mit + und /). Wurde Ihre Nutzlast mit der URL-sicheren Variante (RFC 4648 §5, mit - und _) kodiert, müssen Sie sie vor dem Einbetten zurückkonvertieren – siehe unseren Leitfaden Base64 URL-sicher vs. Standard.

Leerzeichen innerhalb der Nutzlast. Manche Pretty-Printer brechen lange Base64-Zeichenketten bei 76 Spalten mit Zeilenumbrüchen um. Die meisten Browser tolerieren das in <img src>, einige (insbesondere ältere WebViews) jedoch nicht. Entfernen Sie Leerraum vor dem Einbetten: str.replace(/\s+/g, '').

// WANN SIE KEINE data:-URIs VERWENDEN SOLLTEN

Über 50 KB. Cache-Bust und Download-Kosten überwiegen die eingesparte Anfrage.
Wiederholt verwendete Bilder. Alles, was auf mehr als einer Seite eingesetzt wird, sollte eine reguläre URL mit Cache-Headern sein.
Öffentlich zugängliche Analyse. Tracking-Pixel, Beacons und pixelbasierte Attribution funktionieren nicht, weil keine HTTP-Anfrage protokolliert wird.
Vom Benutzer hochgeladene Inhalte, die in einer SPA angezeigt werden. Verwenden Sie stattdessen URL.createObjectURL(blob) – das spart die Base64-Arbeit komplett ein und ist im Speicher rund 4-mal kleiner.
In einer streng konfigurierten CSP-Umgebung, die data: nicht erlaubt. Fügen Sie data: nicht zu Ihrer CSP hinzu, nur um einen Daten-URI zu nutzen; fragen Sie zuerst, ob Sie ihn wirklich brauchen.

// 30-SEKUNDEN-SPICKZETTEL

Format: data:[mime-type][;base64],[payload]

Häufigste Form: data:image/png;base64,iVBORw0KGgo...

Zurück in ein Bild dekodieren: in unseren Base64-zu-Bild-Konverter einfügen.

Bild in einen Daten-URI kodieren: verwenden Sie unseren Bild-zu-Base64-Konverter – er erzeugt den vollständigen data:-URI, bereit zum Einfügen.

Inline-Budget: < 4 KB immer einbetten, 4–50 KB kommt darauf an, > 50 KB lieber eine reguläre URL.

Browser-API: canvas.toDataURL(), FileReader.readAsDataURL() oder bauen Sie die Zeichenkette einfach selbst: 'data:image/png;base64,' + btoa(binaryString).

Weiterführende Lektüre: Base64-Bildeinbettung · Base64-Bilder im Browser vorschauen · Base64 vs. Base64URL vs. Base32