Скопируйте изображение в буфер обмена, используя JavaScript - PullRequest
0 голосов
/ 25 февраля 2020

Я пытаюсь скопировать изображение в буфер обмена , используя JavaScript. Я пробовал эти решения , но получаю ошибку:

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

Есть эта статья , которая показывает:

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.

Я также пытался преобразовать URI данных изображения в BLOB-объект и используя:

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

... но это также дает следующую ошибку:

Uncaught (in promise) DOMException: Document is not focused

Обратите внимание, что мне нужно делать это только с локальными изображениями загружено на стороне клиента (имеет URI данных в качестве источника). Таким образом, все находится на одном сервере и не требует серверной части.

Ответы [ 2 ]

1 голос
/ 25 февраля 2020

Если вы пытаетесь получить изображение из домена, которым вы не управляете, вам нужно будет внедрить некоторый код на стороне сервера, чтобы загрузить изображение в ваш домен, чтобы избежать проблем с несколькими источниками. Если вы будете извлекать изображение из домена, которым вы управляете, вам нужно предоставить изображения с заголовком CORS. Access-Control-Allow-Origin: * или Access-Control-Allow-Origin: https://domain-you-are-fetching-from.example.

Редактировать: Если вы используете существующие URI данных, вы можете преобразовать их в BLOB-объекты без использования fetch. См. Blob from DataURL?

Вы также можете загрузить URI данных в элемент изображения, записать это изображение на холст и использовать метод 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>
0 голосов
/ 25 февраля 2020

На самом деле ваш код на 100% корректен, но по соображениям безопасности пользователь должен сосредоточиться на документе, чтобы что-то скопировать. Вы можете добавить событие клика, чтобы скопировать тест.

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