Formati web personalizzati per l'API Async Clipboard

Fino a questo momento, l'API Async Clipboard supportava un insieme limitato di tipi MIME da copiare e incollare negli appunti di sistema, in particolare: text/plain,text/html e image/png. In genere, il browser esegue la sanitizzazione per, ad esempio, rimuovere elementi script o link javascript: incorporati da una stringa HTML o per impedire attacchi di bombe di decompressione PNG.

In alcuni casi, però, può essere opportuno supportare i contenuti non sottoposti a sanificazione nella clipboard:

  • Situazioni in cui l'applicazione gestisce la sanificazione stessa.
  • Situazioni in cui è fondamentale che i dati copiati siano identici a quelli incollati.

Per questi casi, l'API Async Clipboard ora supporta formati personalizzati web che consentono agli sviluppatori di scrivere dati arbitrari negli appunti.

Supporto browser

L'API Async Clipboard per se con il supporto delle immagini è supportata a partire da Chromium 76. I formati personalizzati web per l'API Async Clipboard sono supportati su Chromium per computer e dispositivi mobili a partire dalla versione 104.

Scrittura di formati personalizzati web negli appunti

Scrivere formati personalizzati web negli appunti è quasi identico alla scrittura di formati sanitizzati, tranne che per l'obbligo di anteporre la stringa "web " (incluso lo spazio finale) al tipo MIME del blob.

// Fetch remote JPEG and GIF images and obtain their blob representations.
const [jpegBlob, gifBlob] = await Promise.all([
  fetch('image.jpg').then((response) => response.blob()),
  fetch('image.gif').then((response) => response.blob()),
]);

try {
  // Write the image data to the clipboard, prepending the blobs' actual
  // types (`"image/jpeg"` and "image/gif") with the string `"web "`, so
  // they become `"web image/jpeg"` and `"web image/gif"` respectively.
  // The code elegantly makes use of computed property names:
  // https://developer.mozilla.org/docs/Web/JavaScript/Reference/Operators/Object_initializer#computed_property_names.
  const clipboardItem = new ClipboardItem({
    [`web ${jpegBlob.type}`]: jpegBlob,
    [`web ${gifBlob.type}`]: gifBlob,
  });
  await navigator.clipboard.write([clipboardItem]);
} catch (err) {
  console.error(err.name, err.message);
}

Lettura dei formati personalizzati web dagli appunti

Come per la scrittura, la lettura dei formati personalizzati web dagli appunti è quasi identica alla lettura dei formati sottoposti a sanificazione. L'unica differenza è che ora l'app deve cercare gli elementi della clipboard il cui tipo inizia con "web ".

try {
  // Iterate over all clipboard items.
  const clipboardItems = await navigator.clipboard.read();
  for (const clipboardItem of clipboardItems) {
    for (const type of clipboardItem.types) {
      // Discard any types that are not web custom formats.
      if (!type.startsWith('web ')) {
        continue;
      }
      const blob = await clipboardItem.getType(type);
      // Sanitize the blob if you need to, then process it in your app.
    }
  }
} catch (err) {
  console.error(err.name, err.message);
}

Interoperabilità con app specifiche della piattaforma

I formati personalizzati web come web image/jpeg non sono compresi dalle applicazioni specifiche per piattaforma (poiché si aspettano image/jpeg). Nel tempo, le app interessate dovrebbero aggiungere il supporto di questi formati come opzione se i relativi sviluppatori ritengono che il supporto dei formati personalizzati web sia pertinente per i loro utenti. Negli appunti del sistema operativo, i vari formati sono presenti in vari formati pronti per l'utilizzo, come si può vedere nello screenshot di macOS riportato di seguito.

Clipboard Expector su macOS che mostra una mappa dei formati personalizzati che elenca due formati personalizzati web.

Demo

Puoi provare la demo e visualizzare il codice sorgente per scoprire come funziona.

Ringraziamenti

Questo documento è stato esaminato da Joe Medley e François Beaufort.