#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 по вопросу