Как переписать функцию, что бы можно было копировать изображения по ссылке?

Есть такая функция, при её вызове копируется изображение, если задать обычный путь из локальной папки, всё работает, а если передать изображение ссылкой, нет. (изображения на сайт приходят ссылкой из базы...)

const copy = async () => {
const image = await fetch(
    'https://iso.500px.com/wp-content/uploads/2016/11/stock-photo-159533631-1500x1000.jpg'
  ),
  blob = await image.blob();

await navigator.clipboard.write([new ClipboardItem({ [blob.type]: blob })]);
};
copy();

Подскажите пожалуйста как исправить, делаю возможность копировать текст и изображения, с текстом было намного проще)


Ответы (1 шт):

Автор решения: Neverm1ndo

Ошибки не пробовали отлавливать?

const copy = () => fetch('https://iso.500px.com/wp-content/uploads/2016/11/stock-photo-159533631-1500x1000.jpg')
                        .then((res) => res.blob())
                        .then((blob) => {
                          return navigator.clipboard.write([new ClipboardItem({ [blob.type]: blob })]);
                        });

copy().catch(console.error); // Type image/jpeg not supported on write.

ClipboardItem не поддерживает MIME image/jpeg.

Чтобы этой ошибки не возникало, можно конвертить image/jpeg в image/png:

const button = document.querySelector('button');

const copy = () => fetch('https://iso.500px.com/wp-content/uploads/2016/11/stock-photo-159533631-1500x1000.jpg')
                        .then((res) => res.blob())
                        .then(convertJPEGtoPNG)
                        .then((blob) => {
                          console.log('Изображение скопировано');
                          return navigator.clipboard.write([new ClipboardItem({ [blob.type]: blob })]);
                        });

function convertJPEGtoPNG(blob) {
  return new Promise((resolve, reject) => {
    if (blob.type !== 'image/jpeg') resolve(blob);
    const canvas = document.createElement('canvas');
    const ctx = canvas.getContext('2d');
    const img = new Image();
          img.src = URL.createObjectURL(blob);
          img.onload = function() {
            canvas.width = img.width;
            canvas.height = img.height;

            ctx.drawImage(img, 0, 0);

            canvas.toBlob((blob) => { resolve(blob) }, 'image/png');
          };
  });
}

// Важно, чтобы Document был в фокусе, иначе получите 'DOMException'
button.addEventListener('click', () => {
  copy().catch(console.error); // Теперь ошибки нет
});
<button>Copy</button>

В сниппете доступ к клипборду блочится, в нем он по дефолту работать не будет(надо наверное доступ запрашивать через navigator.clipboard.permissions.query(), проверять не стал). На CodePen точно работает, можно потыкать.

→ Ссылка