现代风
使用 Web Share API 的 share()
方法
如需共享文件,请调用 navigator.share()
。请注意,在调用 share()
方法之前,您应始终检查文件是否可以通过 navigator.canShare()
共享,并确保您的网站使用 HTTPS。
// Assume `blob` is a PNG image file.
const data = {
files: [
new File([blob], 'image.png', {
type: blob.type,
}),
],
title: 'My title',
text: 'My text',
};
if (navigator.canShare(data)) {
await navigator.share(data);
}
经典路线
在 Web Share API 不受支持的情况下,为用户提供的第二大优势是允许用户下载文件,以便他们手动分享文件,例如通过电子邮件、即时通讯工具/在线社交网络应用分享。
渐进式增强
如果浏览器支持 Web Share API,并且系统可根据支持的文件类型分享数据,以下方法就会使用它。 否则,它会回退到下载文件。
const button = document.querySelector('button');
const img = document.querySelector('img');
// Feature detection
const webShareSupported = 'canShare' in navigator;
// Update the button action text.
button.textContent = webShareSupported ? 'Share' : 'Download';
const shareOrDownload = async (blob, fileName, title, text) => {
// Using the Web Share API.
if (webShareSupported) {
const data = {
files: [
new File([blob], fileName, {
type: blob.type,
}),
],
title,
text,
};
if (navigator.canShare(data)) {
try {
await navigator.share(data);
} catch (err) {
if (err.name !== 'AbortError') {
console.error(err.name, err.message);
}
} finally {
return;
}
}
}
// Fallback implementation.
const a = document.createElement('a');
a.download = fileName;
a.style.display = 'none';
a.href = URL.createObjectURL(blob);
a.addEventListener('click', () => {
setTimeout(() => {
URL.revokeObjectURL(a.href);
a.remove();
}, 1000)
});
document.body.append(a);
a.click();
};
button.addEventListener('click', async () => {
const blob = await fetch(img.src).then(res => res.blob());
await shareOrDownload(blob, 'cat.png', 'Cat in the snow', 'Getting cold feet…');
});
深入阅读
演示
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link
rel="icon"
href="data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 100 100%22><text y=%22.9em%22 font-size=%2290%22>🎉</text></svg>"
/>
<title></title>
<link rel="stylesheet" href="style.css" />
<!-- TODO: Devsite - Removed inline handlers -->
<!-- <script src="script.js" type="module"></script> -->
</head>
<body>
<h1>Share a file</h1>
<img
width="200"
height="200"
alt="A cat walking in the snow."
src="cat.png"
/>
<button type=button></button>
</body>
</html>
:root {
color-scheme: dark light;
}
html {
box-sizing: border-box;
}
*,
*:before,
*:after {
box-sizing: inherit;
}
body {
margin: 1rem;
font-family: system-ui, sans-serif;
}
img,
video {
height: auto;
max-width: 100%;
display: block;
}
button {
margin: 1rem;
}
const button = document.querySelector('button');
const img = document.querySelector('img');
const webShareSupported = 'canShare' in navigator;
button.textContent = webShareSupported ? 'Share' : 'Download';
const shareOrDownload = async (blob, fileName, title, text) => {
if (webShareSupported) {
const data = {
files: [
new File([blob], fileName, {
type: blob.type,
}),
],
title,
text,
};
if (navigator.canShare(data)) {
try {
await navigator.share(data);
} catch (err) {
if (err.name !== 'AbortError') {
console.error(err.name, err.message);
}
} finally {
return;
}
}
}
// Fallback
const a = document.createElement('a');
a.download = fileName;
a.style.display = 'none';
a.href = URL.createObjectURL(blob);
a.addEventListener('click', () => {
setTimeout(() => {
URL.revokeObjectURL(a.href);
a.remove();
}, 1000)
});
document.body.append(a);
a.click();
};
button.addEventListener('click', async () => {
const blob = await fetch(img.src).then(res => res.blob());
await shareOrDownload(blob, 'cat.png', 'Cat in the snow', 'Getting cold feet…');
});