Start · Sprachen · JavaScript · Referenz · Clipboard

Clipboard

Schnittstelle

Das <code>Clipboard</code>-Interface bietet über <code>navigator.clipboard</code> asynchronen Lese- und Schreibzugriff auf die Systemzwischenablage (Text und beliebige Datenformate).

seit JavaScript Baseline 2024 (readText/writeText seit 2020 breit Kategorie: webapi

Signatur

interface Clipboard extends EventTarget

Beschreibung

Das Clipboard-Interface gehört zur Async Clipboard API und löst das veraltete document.execCommand("copy") ab. Man erzeugt es nicht selbst. Die einzige Instanz bekommt man über navigator.clipboard (im Worker-Kontext gibt es sie nicht). Alle Methoden arbeiten asynchron und geben ein Promise zurück. Deshalb blockiert ein Zugriff auf die Zwischenablage den Haupt-Thread nicht, auch wenn große Datenmengen wie Bilder übertragen werden.

Das Interface hat vier Methoden:

  • writeText(text): schreibt reinen Text in die Zwischenablage.
  • readText(): liest den Textinhalt der Zwischenablage.
  • write(items): schreibt ein Array von ClipboardItem-Objekten, z. B. HTML oder PNG-Bilder.
  • read(): liest alle Einträge als Array von ClipboardItem-Objekten.

Typische Einsätze sind „Kopieren“-Schaltflächen für Code-Schnipsel, Freigabe-Links oder Gutscheincodes, das Einfügen von Bildern in Web-Editoren und eigene Kopier- und Einfüge-Funktionen in Anwendungen wie Tabellenkalkulationen oder Zeichenprogrammen.

Die Zwischenablage kann sensible Daten enthalten, etwa Passwörter. Darum ist der Zugriff stark eingeschränkt: Er klappt nur in einem sicheren Kontext (HTTPS oder localhost) und meist nur, wenn das Dokument den Fokus hat. Schreiben erfordert in der Regel eine transiente Nutzeraktivierung, also z. B. einen Klick. Lesen verlangt je nach Browser eine Berechtigung (Chromium: clipboard-read) oder eine Bestätigung über ein Kontextmenü (Firefox, Safari).

Rückgabewert

Typ
Promise<void> | Promise<string> | Promise<ClipboardItem[]>
Beschreibung
writeText() und write() geben Promise<void> zurück, readText() gibt Promise<string> zurück und read() gibt Promise<ClipboardItem[]> zurück. Fehlt die Berechtigung oder ist das Dokument nicht fokussiert, wird das Promise mit einer NotAllowedError-DOMException abgelehnt.

Beispiele

Kopieren-Button für einen Code-Schnipsel

const button = document.querySelector('#copy-btn');
const codeBlock = document.querySelector('#snippet');

button.addEventListener('click', async () => {
  try {
    await navigator.clipboard.writeText(codeBlock.textContent);
    button.textContent = 'Kopiert!';
  } catch (err) {
    console.error('Kopieren fehlgeschlagen:', err.name, err.message);
  }
});
Nach dem Klick steht der Inhalt von #snippet in der Zwischenablage; der Button zeigt „Kopiert!“.

Text aus der Zwischenablage in ein Eingabefeld einfügen

const input = document.querySelector('#coupon');

document.querySelector('#paste-btn').addEventListener('click', async () => {
  try {
    const text = await navigator.clipboard.readText();
    input.value = text.trim();
    console.log('Eingefügt:', input.value);
  } catch (err) {
    // NotAllowedError, wenn der Nutzer den Zugriff verweigert
    console.warn('Lesen nicht erlaubt:', err.name);
  }
});
Eingefügt: SOMMER2024

Canvas-Bild als PNG kopieren

const canvas = document.querySelector('canvas');

document.querySelector('#copy-image').addEventListener('click', async () => {
  // Promise<Blob> direkt übergeben – wichtig für Safari (Nutzeraktivierung bleibt erhalten)
  const pngPromise = new Promise((resolve) => canvas.toBlob(resolve, 'image/png'));
  const item = new ClipboardItem({ 'image/png': pngPromise });
  await navigator.clipboard.write([item]);
  console.log('Bild kopiert');
});
Bild kopiert

Alle Formate der Zwischenablage auslesen

document.querySelector('#inspect').addEventListener('click', async () => {
  const items = await navigator.clipboard.read();
  for (const item of items) {
    for (const type of item.types) {
      const blob = await item.getType(type);
      console.log(type, blob.size, 'Bytes');
      if (type === 'image/png') {
        const img = document.createElement('img');
        img.src = URL.createObjectURL(blob);
        document.body.append(img);
      }
    }
  }
});
text/html 312 Bytes text/plain 48 Bytes

// Wichtig · Fallstricke

  • Nur in sicheren Kontexten: Bei http:// (außer localhost) ist navigator.clipboard undefined. Deshalb vor der Nutzung prüfen, z. B. mit if (navigator.clipboard) ….
  • Nutzeraktivierung: Ein Aufruf ohne vorherige Nutzeraktion (z. B. beim Laden der Seite oder in einem setTimeout) wird in Firefox und Safari mit NotAllowedError abgelehnt. Safari beendet die Aktivierung schon, wenn vor write() ein await steht. In diesem Fall ein Promise an ClipboardItem übergeben, wie im Canvas-Beispiel.
  • Fokus: Hat das Dokument keinen Fokus, etwa weil die DevTools geöffnet sind, schlagen die Aufrufe fehl (Document is not focused).
  • Berechtigungen: Chromium fragt beim Lesen die Berechtigung clipboard-read ab. Firefox und Safari zeigen stattdessen ein „Einfügen“-Kontextmenü. In iframes muss die Permissions-Policy (allow="clipboard-read; clipboard-write") gesetzt sein.
  • Formate: Sicher unterstützt werden nur text/plain, text/html und image/png. Eigene Formate mit dem Präfix web gibt es nur in Chromium. Mit ClipboardItem.supports(type) lässt sich die Unterstützung prüfen.
  • Sicherheit: Gelesene Inhalte, besonders text/html, sind nicht vertrauenswürdig. Nie ungeprüft per innerHTML einfügen, sonst droht XSS. Besser textContent oder eine Bereinigung (z. B. DOMPurify) verwenden. Außerdem die Zwischenablage nicht ungefragt überschreiben („Clipboard Hijacking“).
  • Die Events copy, cut und paste (mit ClipboardEvent.clipboardData) sind die synchrone Alternative, um auf Kopier- und Einfügeaktionen des Nutzers zu reagieren.