Como compartilhar arquivos

Equilíbrio
Pagamento de equilíbrio

Para compartilhar arquivos, chame navigator.share(). Observe que é necessário sempre verificar se os arquivos podem ser compartilhados com navigator.canShare() e se o site está usando HTTPS antes de chamar o método share().

// 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);
}

Compatibilidade com navegadores

  • 89
  • 93
  • 12.1

Origem

A forma clássica

A próxima melhor coisa a oferecer ao usuário se não houver suporte para a API Web Share é permitir que o usuário faça o download do arquivo para que ele possa compartilhá-lo manualmente, por e-mail, por um app de mensagens ou de rede social on-line.

Compatibilidade com navegadores

  • 15
  • 13
  • 20
  • 10.1

Origem

Aprimoramento progressivo

O método abaixo usa a API Web Share quando o navegador é compatível e quando os dados podem ser compartilhados com base nos tipos de arquivos compatíveis. Caso contrário, ele volta para o download do arquivo.

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…');
});

Leia mais

Demonstração

<!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…');
});