Не удается использовать Web Share API для совместного использования файла в моем приложении React typescript

#javascript #reactjs #typescript #web-share

#javascript #reactjs #typescript #веб-общий доступ

Вопрос:

Я пытаюсь запустить веб-приложение, которое позволяет обмениваться файлами. После небольшого поиска в Google я нашел Web Share API, похожий на стандарт для этого. Согласно документации, это должно работать так, используя обычный JS

Это код для HTML-страницы

 <p><button>Share MDN!</button></p>
<p class="result"></p>
 

Код для совместного использования всех метаданных сортировки на основе текста:

 let shareData = {
  title: 'MDN',
  text: 'Learn web development on MDN!',
  url: 'https://developer.mozilla.org',
}

const resultPara = document.querySelector('.result');

if (!navigator.canShare) {
  resultPara.textContent = 'navigator.canShare() not supported.';
}
else if (navigator.canShare(shareData)) {
  resultPara.textContent = 'navigator.canShare() supported. We can use navigator.share() to send the data.';
} else {
  resultPara.textContent = 'Specified data cannot be shared.';
}
 

Приведенный выше код работает нормально, проблема возникает, когда я пытаюсь поделиться файлами.

Согласно документации, это должно работать следующим образом:

 // filesArray is an array of files we want to share (audios, images, videos, pdf)
if (navigator.canShare amp;amp; navigator.canShare({ files: filesArray })) {
  navigator.share({
    files: filesArray,
    title: 'Pictures',
    text: 'Our Pictures.',
  })
  .then(() => console.log('Share was successful.'))
  .catch((error) => console.log('Sharing failed', error));
} else {
  console.log(`Your system doesn't support sharing files.`);
}
 

Я начал свой код с этого примера, и мне никогда не удавалось поделиться файлом.
Мой фактический код с использованием React и Typescript выглядит следующим образом:

 //some react code here


      const shareNow = async () => {
        let imageResponse = await window.fetch('https://www.google.com/images/branding/googlelogo/2x/googlelogo_color_272x92dp.png', {mode: "no-cors"});
        let imageBuffer = await imageResponse.arrayBuffer();
        let fileArray = [new File([imageBuffer], "File Name", {
          type: "image/png",
          lastModified: Date.now()
        })];


       if (navigator.canShare amp;amp; navigator.canShare({ files: filesArray })) {
          navigator.share({
            files: filesArray
          }).then(() => {
            console.log('Thanks for sharing!');
          })
          .catch(console.error);
        }

        
      }

//some react code here too
 

На данный момент мой компилятор typescript кричит на меня.
По-видимому, объект navigator не имеет метода canShare()

Компилятор кричит

Я новичок в typescript, но я не понимаю, как и почему у навигатора может быть атрибут less, поскольку TypeScript является надмножеством JavaScript.

У кого-нибудь есть идея о том, как решить эту проблему, кроме запуска обычного JS?

Спасибо, что уделили время чтению этого, и я надеюсь поблагодарить вас за ваши ответы.

P.S: Я также попробовал решение на основе компонентов react, но все компоненты, которые я нашел в open source, которые обертывают Web Share API, не разрешают совместное использование файлов.

Редактировать

Привет, @DenverCoder9

Существует тот же вариант использования, но с использованием vanilla JS, может кто-нибудь попробовать и сказать мне, что я делаю не так, пожалуйста?

 <html>

<head>
    <title>Sharing Image</title>
    <meta charset="UTF-8" />
</head>

<body>
    <div className="App">
        <img src="https://www.google.com/images/branding/googlelogo/2x/googlelogo_color_272x92dp.png"/>
        <button id="button">Share</button>
    </div>
</body>

<script>
    async function shareImage(title, imageUrl) {
        const image = await fetch(imageUrl, {mode: "no-cors"});
        const blob = await image.blob();
        const file = new File([blob], title, { type: 'image/png' });
        const filesArray = [file];

        const shareData = {
        files : filesArray

        }
        // add it to the shareData

        const navigator = window.navigator
        const canShare = navigator.canShare amp;amp; navigator.canShare(shareData)  //navigator.canShare()navigator.share  //navigator.canShare()

        if(canShare){
        navigator.share(shareData)
        .then(() => console.log('Successful share'))
        .catch((error) => console.log('Error sharing', error));
        }
        else {
            console.log("cannot share this file in this context")
        }
    }

    document.getElementById('button').onclick = function() {
    shareImage("Title", "https://www.google.com/images/branding/googlelogo/2x/googlelogo_color_272x92dp.png")
    };
</script>

</html>
 

Я запускаю это в Safari для Mac

Ответ №1:

Это скорее проблема с TypeScript, чем проблема с кодированием. В этом PR была добавлена поддержка API Web Share (уровень 2), поэтому вы можете либо обновиться до версии TypeScript, которая включает это, либо, в качестве альтернативы, обучить вашу текущую версию TypeScript соответствующим типам следующим образом:

 type ShareData = {
    title? : string;
    text? : string;
    url? : string;
    files?: ReadonlyArray<File>;
};

interface Navigator
{
    share? : (data? : ShareData) => Promise<void>;
    canShare?: (data?: ShareData) => boolean;
}
 

Комментарии:

1. Спасибо за ваш ответ @DenverCoder9, я установил версию typescript со всеми типами. Но теперь у меня есть еще одна проблема с использованием share API. Функция `navigator.canShare ({ files: filesArray })` всегда возвращает false, и я не знаю, как прочитать исходный код этой функции, чтобы понять, почему. Во время кодирования эта функция является абстрактной, и во время выполнения через браузер я не могу получить доступ к исходному коду. Есть идеи?

2. Может быть, вы пытаетесь поделиться неподдерживаемыми типами файлов? Смотрите список поддерживаемых в настоящее время типов в MDN.

3. Я надеялся, что это так, но я проверил документацию, и тип «image / png» является принятым. Знаете ли вы, какой инструмент я могу использовать, чтобы иметь возможность видеть исходный код функции ‘canShare ()’ и отлаживать его, исходный код недоступен в отладчике safari / chrome

4. Если вы действительно хотите погрузиться в код браузера, это глубокая ссылка . Вероятно, было бы проще поделиться тестовым примером с вашей проблемой здесь, чтобы сообщество могло отлаживать. Это также может быть проблемой размера (слишком большие файлы изображений).

5. Спасибо @DenverCoder9 Я добавил ванильный JS / html по вопросу