Start · Sprachen · JavaScript · Referenz · Clipboard.read()

Clipboard.read()

Methode

Liest den Inhalt der Zwischenablage asynchron aus und erfüllt das Promise mit einem Array von <code>ClipboardItem</code>-Objekten, z. B. Text, HTML oder Bilder.

seit JavaScript Baseline 2024: Chrome 86+, Edge 86+, Firefox 127+, Kategorie: webapi

Signatur

Clipboard.prototype.read(options)

Beschreibung

Die Methode read() der Clipboard-Schnittstelle, die über navigator.clipboard erreichbar ist, fordert eine Kopie des aktuellen Zwischenablage-Inhalts an. Anders als readText(), das nur reinen Text liefert, gibt read() beliebige unterstützte Datentypen zurück, etwa text/plain, text/html oder image/png.

Das zurückgegebene Promise wird mit einem Array von ClipboardItem-Objekten erfüllt. Jedes Element hat die Eigenschaft types mit den verfügbaren MIME-Typen. Über getType(mimeType) bekommt man die Daten zu einem Typ als Blob. So lässt sich etwa ein eingefügter Screenshot direkt als Bild in der Seite anzeigen oder hochladen.

Weil die Zwischenablage sensible Daten enthalten kann, ist der Zugriff stark eingeschränkt. Die Seite muss in einem sicheren Kontext (HTTPS oder localhost) laufen und in der Regel den Fokus haben. Je nach Browser ist außerdem eine Berechtigung (clipboard-read) oder eine vorübergehende Benutzeraktivierung nötig, also z. B. ein Klick auf einen Button. Rufen Sie read() deshalb am besten direkt in einem Klick-Handler auf.

Parameter

Name Typ Default Beschreibung
$options Object {} Optionales Objekt mit Leseoptionen. Chromium unterstützt unsanitized: ein Array von MIME-Typen (derzeit nur ["text/html"]), die nicht bereinigt zurückgegeben werden sollen. Kein Standard in allen Browsern.

Rückgabewert

Typ
Promise<ClipboardItem[]>
Beschreibung
Ein Promise, das mit einem Array von ClipboardItem-Objekten erfüllt wird. Es wird mit einer NotAllowedError-DOMException abgelehnt, wenn der Zugriff verweigert wird, und mit DataError, wenn keine lesbaren Daten vorhanden sind (browserabhängig).

Beispiele

Alle Typen in der Zwischenablage auflisten

const button = document.querySelector('#inspect');

button.addEventListener('click', async () => {
  try {
    const items = await navigator.clipboard.read();
    for (const item of items) {
      console.log('Verfügbare Typen:', item.types);
    }
  } catch (err) {
    console.error('Zugriff fehlgeschlagen:', err.name, err.message);
  }
});
Verfügbare Typen: ['text/plain', 'text/html']

Eingefügtes Bild anzeigen (z. B. Screenshot)

const pasteBtn = document.querySelector('#paste-image');
const preview = document.querySelector('#preview'); // <img>-Element

pasteBtn.addEventListener('click', async () => {
  try {
    const items = await navigator.clipboard.read();
    const imageItem = items.find((item) =>
      item.types.some((type) => type.startsWith('image/'))
    );

    if (!imageItem) {
      console.log('Kein Bild in der Zwischenablage.');
      return;
    }

    const imageType = imageItem.types.find((t) => t.startsWith('image/'));
    const blob = await imageItem.getType(imageType);
    preview.src = URL.createObjectURL(blob);
    console.log(`Bild geladen: ${imageType}, ${blob.size} Bytes`);
  } catch (err) {
    console.error('Konnte Bild nicht lesen:', err);
  }
});
Bild geladen: image/png, 48213 Bytes

HTML bevorzugen, auf Text zurückfallen

const readRichContent = async () => {
  const [item] = await navigator.clipboard.read();
  if (!item) return null;

  if (item.types.includes('text/html')) {
    const blob = await item.getType('text/html');
    return { type: 'html', content: await blob.text() };
  }
  if (item.types.includes('text/plain')) {
    const blob = await item.getType('text/plain');
    return { type: 'text', content: await blob.text() };
  }
  return null;
};

document.querySelector('#paste').addEventListener('click', async () => {
  const result = await readRichContent();
  console.log(result);
});
{ type: 'html', content: '<b>Hallo</b> Welt' }

Berechtigung vorab prüfen (Chromium)

const canReadClipboard = async () => {
  if (!navigator.clipboard?.read) return false;
  try {
    const status = await navigator.permissions.query({ name: 'clipboard-read' });
    return status.state !== 'denied';
  } catch {
    // Firefox/Safari kennen 'clipboard-read' in der Permissions API nicht
    return true;
  }
};

canReadClipboard().then((ok) => console.log('Lesen möglich:', ok));
Lesen möglich: true

// Wichtig · Fallstricke

  • Nur in sicheren Kontexten: navigator.clipboard gibt es nur über HTTPS oder localhost. Über HTTP ist es undefined.
  • Berechtigungen unterscheiden sich je nach Browser: Chromium fragt über die Permissions API nach der Berechtigung clipboard-read. Firefox und Safari verlangen stattdessen eine Benutzeraktivierung und zeigen ein kleines Kontextmenü „Einfügen“ an, das der Nutzer bestätigen muss. permissions.query({ name: 'clipboard-read' }) wirft in Firefox und Safari einen Fehler.
  • Fokus nötig: Hat das Dokument keinen Fokus (z. B. weil die DevTools aktiv sind), wird das Promise mit NotAllowedError abgelehnt.
  • In iframes muss der Zugriff mit allow="clipboard-read" (Permissions Policy) freigegeben werden.
  • Eingeschränkte Formate: Browser liefern meist nur text/plain, text/html und image/png. Andere Bildformate werden oft zu PNG umgewandelt. Eigene Formate mit dem Präfix web (Web Custom Formats) gibt es nur in Chromium.
  • Sicherheit: Chromium bereinigt HTML aus der Zwischenablage standardmäßig. Wer unsanitized nutzt oder das HTML per innerHTML einfügt, riskiert XSS. Bereinigen Sie fremdes HTML vorher, z. B. mit DOMPurify oder der Sanitizer API.
  • Für reinen Text ist readText() einfacher. Im paste-Event ist event.clipboardData ohne zusätzliche Berechtigung verfügbar und oft die robustere Wahl.
  • Mit URL.createObjectURL() erzeugte URLs sollten Sie mit URL.revokeObjectURL() wieder freigeben, sonst bleibt der Speicher belegt.