navigator.share 文件在 iOS 14 Safari 上不起作用

Posted

技术标签:

【中文标题】navigator.share 文件在 iOS 14 Safari 上不起作用【英文标题】:navigator.share file not working on iOS 14 Safari 【发布时间】:2021-03-16 19:18:42 【问题描述】:

我正在尝试向我的网页添加一个使用 Web Share API 共享图像和视频的选项。在测试它时,我遇到以下问题:在 android + Chrome 上,它可以共享视频和图像,但是当我在 ios 14.4 Safari(在 iPhone 6s 上运行)上执行相同的代码时,我只能得到文本和 URL 共享,不是文件。有人有同样的问题吗?基于此,它应该可以工作:https://caniuse.com/web-share

https://jsfiddle.net/ryb0x537/

问候。

<div id="error"></div>
<form method="POST" action="/share/">
  <table>
    <tr>
      <td><label for="shared_title">Title:</label></td>
      <td><input id="shared_title" name="shared_title" value="Example Title"></td>
    </tr>
    <tr>
      <td><label for="shared_text">Text:</label></td>
      <td><input id="shared_text" name="shared_text" value="Example text"></td>
    </tr>
    <tr>
      <td><label for="shared_url">URL:</label></td>
      <td><input id="shared_url" name="shared_url" value="https://example.com/a?b=c"></td>
    </tr>
    <tr>
      <td><label for="shared_file">File(s):</label></td>
      <td><input id="shared_file" name="shared_file" type="file" multiple></td>
    </tr>
  </table>
  <input type="submit" value="Share">
</form>
<script>
document.querySelector('form').onsubmit = () => 
  const error = document.getElementById('error');
  const title = document.getElementById('shared_title').value;
  const text = document.getElementById('shared_text').value;
  const url = document.getElementById('shared_url').value;
  const files = document.getElementById('shared_file').files;

  let data = ;
  if (files.length > 0) 
    data.files = files;
  
  if (title !== '')
    data.title = title;
  if (text !== '')
    data.text = text;
  if (url !== '')
    data.url = url;

  error.textContent = '';
  navigator.share(data)
    .then(() => 
  )
    .catch((err) => 
    console.log('Unsuccessful share');
    error.textContent = 'Share failed: ' + err.message;
  );

  return false;
;
</script>

【问题讨论】:

【参考方案1】:

Safari 似乎在处理文件对象和阻塞方面存在问题(抛出 TypeError)。我可以通过使用转换为文件的 blob 来让它工作:

const blob = await fetch('https://cdn.glitch.com/f96f78ec-d35d-447b-acf4-86f2b3658491%2Fchuck.png?v=1618311092497').then(r=>r.blob())

const share = async (title, text, blob) => 
  const data = 
    files: [
      new File([blob], 'image.png', 
        type: blob.type,
      ),
    ],
    title: title,
    text: text,
  ;
  try 
    if (!(navigator.canShare(data))) 
      throw new Error('Can\'t share data.', data);
    ;
    await navigator.share(data);
   catch (err) 
    console.error(err.name, err.message);
  
;

【讨论】:

我尝试了您的解决方案,但它仍然只能在 Android 上进行文件共享。我正在使用临时 ssl 上下文在本地服务器上运行。这是代码:jsfiddle.net/5gtoLw7b/3 对不起。我尝试了其他应用程序,并且:在 IOS/Safari 上,图像现在似乎在文本中的 Message 和 Gmail 等应用程序上共享。在 Whatsapp 上仅发送可变文本。是预期的吗?我正在使用临时 ssl 上下文在本地服务器上运行。这是代码:jsfiddle.net/5gtoLw7b/3 在 Whatsapp 上共享:在 Safari 上不发送文本(仅图像)有效。如果我尝试发送两者,它只会发送文本内容 您的代码绝对正确。奇怪的是 WhatsApp 的共享实现。我只分享了一张图片(没有任何附带的文字)就让它工作了:js const data = files: [ new File([blob], 'image.png', type: blob.type, ), ], ; try if (!(navigator.canShare(data))) throw new Error('Can\'t share data.', data); ; await navigator.share(data); catch (err) console.error(err.name, err.message); Messages 或 Gmail 等其他应用程序正确处理了初始代码,只是 WhatsApp 关闭了。

以上是关于navigator.share 文件在 iOS 14 Safari 上不起作用的主要内容,如果未能解决你的问题,请参考以下文章

navigator.share 打开一个较小的菜单

“导航器”类型上不存在属性“共享”

我可以在 Safari 上使用 Web Share API 共享文件吗

Firebase 日志事件

Web 共享 API:某些文件类型的权限被拒绝

Safari 桌面 Web 共享 API 中缺少“复制”选项?