使用 JavaScript 将图像复制到剪贴板

Copy image to clipboard using JavaScript

我正在尝试使用 JavaScript将图像复制到剪贴板。我已尝试 these solutions 但出现错误:

Uncaught (in promise) DOMException: Document is not focused.

有这个 article 显示:

try {
  const imgURL = '/images/generic/file.png';
  const data = await fetch(imgURL);
  const blob = await data.blob();
  await navigator.clipboard.write([
    new ClipboardItem({
      [blob.type]: blob
    })
  ]);
  console.log('Image copied.');
} catch(e) {
  console.error(e, e.message);
}

但这给出了错误:

VM2303:12 TypeError: Failed to fetch "Failed to fetch"

...以及 CORS 警告。

我也试过 converting an image data URI into a blob 并使用:

navigator.clipboard.write([
    new ClipboardItem({
        'image/png': blob
    })
])

...但这也会出现以下错误:

Uncaught (in promise) DOMException: Document is not focused

请注意,我只需要对 本地图像 上传的客户端(具有数据 URI 作为源)执行此操作。所以一切都在同一台服务器上,不需要后端。

实际上,您的代码是 100% 正确的,但出于安全原因,用户必须专注于文档才能复制任何内容。 您可以添加一个点击事件来复制测试。

button.onclick = ()=>{
    copyImage();
};

如果您尝试从不受您控制的域中获取图像,则需要执行一些 server-side 代码来将图像提取到您的域中,以避免 cross-origin 问题。如果您要从您控制的域中获取图像,则需要使用 CORS header 来提供图像。 Access-Control-Allow-Origin: *Access-Control-Allow-Origin: https://domain-you-are-fetching-from.example.

编辑: 如果您使用现有的数据 URI,则可以将它们转换为 blob,而无需使用 fetch。参见 Blob from DataURL?

您还可以在图像元素中加载数据 URI,将该图像写入 canvas,然后使用 canvas.toBlob() 方法生成 blob。

const image = document.getElementsByTagName('img')[0]
image.addEventListener('click', e => {
  const canvas = document.createElement('canvas')
  canvas.width = image.naturalWidth
  canvas.height = image.naturalHeight
  const context = canvas.getContext('2d')
  context.drawImage(image, 0, 0)
  canvas.toBlob(blob => {
    navigator.clipboard.write([
      new ClipboardItem({
        [blob.type]: blob
      })
    ]).then(() => {
      console.log('Copied')
    })
  })
})
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  <img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mP8z/C/HgAGgwJ/lK3Q6wAAAABJRU5ErkJggg==" width="20" alt="">
</body>
</html>