如何共享文件

黎明 (Palances Liao)
Palances Liao

如需共享文件,请调用 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);
}

浏览器支持

  • 89
  • 93
  • 12.1

来源

经典路线

在 Web Share API 不受支持的情况下,为用户提供的第二大优势是允许用户下载文件,以便他们手动分享文件,例如通过电子邮件、即时通讯工具/在线社交网络应用分享。

浏览器支持

  • 15
  • 13
  • 20
  • 10.1

来源

渐进式增强

如果浏览器支持 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…');
});