Search code examples
javascriptblobclipboard

Copy image to clipboard using JavaScript


I am trying to copy an image to clipboard using JavaScript. I have tried these solutions but get the error:

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

There is this article which shows:

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);
}

But this gives the error:

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

...along with CORS warning.

I have also tried converting an image data URI into a blob and using:

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

...but this also gives the following error:

Uncaught (in promise) DOMException: Document is not focused

Note that I only need to do this with local images uploaded client-side (has a data URI as source). So everything is on the same server and requires no back-end.


Solution

  • If you are trying to fetch an image from a domain you don't control, you will need to implement some server-side code to fetch the image to your domain to avoid cross-origin issues. If you will be fetching the image from a domain you control, you need to serve the images with the CORS header. Access-Control-Allow-Origin: * or Access-Control-Allow-Origin: https://domain-you-are-fetching-from.example.

    Edit: If you are using existing data URIs, you can convert them to blobs without using fetch. See Blob from DataURL?

    You could also load the data URI in an image element, write that image to a canvas, and use the canvas.toBlob() method to produce a 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>