Web Share API:从浏览器调起原生分享面板
一句话: navigator.share() 调起平台的原生分享面板——和用户在原生应用中看到的同一个
系统级对话框——让他们把 URL、标题、文本或文件发送给设备上安装的任意应用,无需你自己构建
分享 UI。
可以分享什么
Section titled “可以分享什么”navigator.share() 接受一个选项对象,可包含以下任意组合:
url— 绝对 URL(通常默认为当前页面)。title— 可选提示;接收应用通常会忽略它。text— 除 URL 外或替代 URL 的自由文本。files—File对象数组(图片、音频、视频、文本文件、PDF)。 分享文件前必须先调用canShare({ files })检查(见下文)。
// 特性检测后再分享async function share() { if (!navigator.share) { // 回退:复制 URL 到剪贴板 await navigator.clipboard.writeText(location.href); return; } try { await navigator.share({ title: document.title, url: location.href, }); } catch (err) { if (err.name !== 'AbortError') throw err; // 用户取消——不是错误 }}用户手势要求
Section titled “用户手势要求”navigator.share() 必须在用户激活(点击、按键或类似瞬时事件)时调用。从定时器、
DOMContentLoaded 或任何已失去激活的异步上下文中调用会抛出 NotAllowedError。这是
规范中定义的浏览器安全性不变量。
安全上下文(HTTPS)
Section titled “安全上下文(HTTPS)”Web Share API 仅在安全上下文中可用——HTTPS 或 localhost。在普通 HTTP 下,无论
什么浏览器,该 API 均为 undefined。
用 canShare 检查文件分享支持
Section titled “用 canShare 检查文件分享支持”不同平台和浏览器支持的文件类型不尽相同。传入 files 之前请先检查:
const supported = navigator.canShare?.({ files: myFiles });if (supported) { await navigator.share({ files: myFiles, title: '照片' });} else { // 提供替代方案:下载链接、复制 URL 等}当给定数据无法分享时(例如文件类型不在浏览器许可名单内,或完全不支持文件分享),
navigator.canShare() 返回 false 而非抛出异常。
Web Share Target
Section titled “Web Share Target”PWA 也可以通过在 manifest 中声明 share_target 来接收来自其他应用的分享。这是一个
独立机制——详见 Manifest share_target 参考。Web Share API(本页)仅涵盖发送端。
浏览器与生态支持
Section titled “浏览器与生态支持”当前各浏览器数据请参见 /compatibility/。
决策判定框架
Section titled “决策判定框架”| 决策问题 | 建议行为 | 理由 |
|---|---|---|
| 想在所有平台提供分享功能? | 仅在用户手势后调用 navigator.share();undefined 时提供剪贴板回退。 |
该 API 并非通用;优雅降级保证功能可访问。 |
| 分享文件而非仅 URL? | 调用前检查 navigator.canShare({ files })。 |
文件分享支持因浏览器和平台而异。 |
| 同时想接收来自其他应用的分享? | 在 manifest 中添加 share_target。 |
Web Share Target 是独立于发送 API 的另一机制。 |
| 需要统计分享事件? | 在 navigator.share() Promise 解析后记录。 |
Promise 在用户操作后解析;AbortError 表示用户取消。 |
- 用
if (navigator.share)做门控,并提供回退(剪贴板或自定义 UI)。 - 仅在用户手势事件处理器内调用
navigator.share()。 - 通过 HTTPS 提供页面——普通 HTTP 下 API 不可用。
- 静默捕获
AbortError;仅向用户展示其他错误。 - 分享文件前使用
navigator.canShare({ files })。 - 不要依赖
title字段的显示效果——各接收应用处理方式不一致。