对 Async Clipboard API 的 SVG 支持

Async Clipboard API 的 Clipboard 接口提供对系统剪贴板内容的读写权限。这允许 Web 应用实现剪切、复制和粘贴功能。您可以通过调用 read() 方法将数据从剪贴板粘贴到应用,并通过调用 write() 方法将数据复制到剪贴板。除了文本、便携式网络图形 (PNG) 格式的图片、经过净化和未净化的 HTML 以及网络自定义格式外,Async Clipboard API 现在还支持复制和粘贴 SVG 图片,这意味着您最终可以与处理 SVG 图片的图片编辑软件交互,具体方法是复制作为 SVG 文字进行复制,而不是以图片形式复制 SVG 图片。

功能检测 SVG 支持

通过调用静态 ClipboardItem.supports() 方法并向其传递所需的 MIME 类型,检测对 SVG 图片(以及任何其他 MIME 类型)的支持情况。

const supportsSVG = () => {
  if (
    !('supports' in window.ClipboardItem) ||
    !window.ClipboardItem.supports('image/svg+xml')
  ) {
    return false;
  }
  return true;
};

复制 SVG 图片

通过使用对象填充 ClipboardItem 来复制 SVG 图片。包含 SVG 图片数据的 blob 是值,将 blob 的类型(在本例中为 'image/svg+xml')作为其键。

copyButton.addEventListener('click', async () => {
  if (!supportsSVG()) {
    return;
  }
  try {
    const blob = await fetch(img.src).then((response) => response.blob());
    await navigator.clipboard.write([
      new window.ClipboardItem({
        [blob.type]: blob,
      }),
    ]);
  } catch (err) {
    console.error(err.name, err.message);
    alert(err.message);
  }
});

粘贴 SVG 图片

如需粘贴 SVG 图片,请从剪贴板中读取 ClipboardItem,并使用 getType() 方法获取所需的类型(在本例中为 'image/svg+xml')。这将返回一个 blob,转换为 blob 网址后,您可以将其分配给 <img>src 属性。

pasteButton.addEventListener('click', async () => {
  if (!supportsSVG()) {
    return;
  }
  const [clipboardItem] = await navigator.clipboard.read();
  const svgBlob = await clipboardItem.getType('image/svg+xml');
  if (!svgBlob) {
    alert('No SVG in the clipboard.');
    return;
  }
  const image = document.createElement('img');
  const blobURL = URL.createObjectURL(svgBlob);
  image.addEventListener('load', () => {
    URL.revokeObjectURL(blobURL);
  });
  image.src = blobURL;
});

排错

SVG 是一种功能强大的格式,例如,它允许嵌入的脚本。如果用户粘贴来自未知来源的内容,这可能会有危险,因此浏览器会运行清理步骤。复制数据时,Async Clipboard API 会生成格式正确的 SVG 文档,然后将其写入剪贴板。粘贴数据时,fragment 解析器会生成经过严格处理的 SVG fragment。因此,在执行粘贴操作之前,onclick 事件处理脚本属性仍然存在,但在粘贴时,它们会被移除。

macOS 上的 Clipboard Viewer 应用,用于检查剪贴板内容。这表明 SVG 中的 onClick 事件监听器属性仍然存在。
macOS 上的剪贴板查看器应用检查剪贴板内容。这表明 SVG 中的 onClick 事件监听器属性仍然存在。

演示

观看 Glitch 上的演示,了解如何复制和粘贴 SVG。查看源代码以了解其工作原理。在复制和粘贴之后,请务必尝试点击 任意圆圈。粘贴后,潜在的危险 onclick 事件处理脚本属性会被移除。

致谢

对 Chromium 中 Async Clipboard API 的 SVG 支持由 Microsoft Edge 团队完成。此帖由 Rachel Andrew 和 Anupam Snigdha 审核。