背景与核心价值原生系统分享可显著提升传播链路与用户转化,Share Target 让 PWA 成为系统级“接收端”。统一实现方案覆盖文本/链接/文件的分享与接收,兼容非支持环境的回退逻辑。在保证隐私与权限最小化的前提下,提供可度量的成功率与交互效率指标。兼容性与前置条件`Web Share API`:Chrome/Edge/Android 上广泛支持;桌面端支持分享文本/URL,移动端支持文件分享。`Share Target`:需安装的 PWA(添加到桌面/主屏)才可作为系统分享目标;iOS Safari 暂不支持 Share Target(提供回退方案)。需具备 `manifest.json` 与 `Service Worker`,并通过 HTTPS 部署。发送分享:feature detection 与渐进增强function canNativeShare(payload: ShareData): boolean {

// 桌面端不支持文件分享,移动端支持;统一做能力检测

// @ts-expect-error: navigator.canShare在部分环境是实验性

const canShareFiles = typeof navigator.canShare === 'function' && payload.files && payload.files.length > 0

? navigator.canShare({ files: payload.files })

: true;

return !!navigator.share && canShareFiles;

}

export async function share(payload: ShareData) {

if (canNativeShare(payload)) {

try {

await navigator.share(payload);

return { ok: true };

} catch (err) {

// 用户取消或系统拒绝

return { ok: false, error: String(err) };

}

}

// 回退:复制链接或文本到剪贴板

if (payload.url) {

await navigator.clipboard.writeText(`${payload.title ? payload.title + "\n" : ''}${payload.text ? payload.text + "\n" : ''}${payload.url}`);

return { ok: true, fallback: 'clipboard' };

}

if (payload.text) {

await navigator.clipboard.writeText(payload.text);

return { ok: true, fallback: 'clipboard' };

}

return { ok: false, error: 'no-capability' };

}

// 示例:分享文件(移动端)

async function shareImage(blob: Blob) {

const file = new File([blob], 'image.jpg', { type: 'image/jpeg' });

const payload: ShareData = { title: '示例图片', text: '来自应用的图片', files: [file] };

return share(payload);

}

注意事项:必须由用户手势触发(如点击按钮);否则浏览器会拒绝。文件类型与大小:建议图片/视频≤20MB,单次分享文件数≤10(依据移动端稳定性经验)。Share Target:在 PWA 中接收系统分享manifest.json 配置示例:{

"name": "示例应用",

"start_url": "/",

"display": "standalone",

"share_target": {

"action": "/share-target",

"method": "POST",

"enctype": "multipart/form-data",

"params": {

"title": "title",

"text": "text",

"url": "url",

"files": [{ "name": "files", "accept": ["image/*", "video/*", "text/plain"] }]

}

}

}

Service Worker 拦截 share target 的 POST:self.addEventListener('fetch', (event: FetchEvent) => {

const url = new URL(event.request.url);

if (event.request.method === 'POST' && url.pathname === '/share-target') {

event.respondWith(handleShareTarget(event.request));

}

});

async function handleShareTarget(req: Request): Promise<Response> {

const form = await req.formData();

const title = form.get('title')?.toString() || '';

const text = form.get('text')?.toString() || '';

const url = form.get('url')?.toString() || '';

const files = form.getAll('files') as File[];

const payload = {

title, text, url,

filesMeta: files.map(f => ({ name: f.name, size: f.size, type: f.type }))

};

const clientsList = await self.clients.matchAll({ type: 'window', includeUncontrolled: true });

if (clientsList.length) {

clientsList[0].postMessage({ type: 'share-target', payload });

return Response.redirect('/share', 303);

}

await self.clients.openWindow('/share');

return Response.redirect('/share', 303);

}

页面接收消息并渲染:navigator.serviceWorker.addEventListener('message', (e: MessageEvent) => {

if (e.data?.type === 'share-target') {

const p = e.data.payload as { title: string; text: string; url: string; filesMeta: Array<{name:string;size:number;type:string}> };

renderSharePayload(p);

}

});

function renderSharePayload(p: any) {

// 将内容展示在 /share 页面,文件可发起进一步处理/上传

}

隐私与安全治理最小化参数:仅在必要时收集 `title/text/url/files`;不在 SW 中持久化原始文件,优先页面态处理并征得用户同意。类型白名单:`accept` 限制文件类型;上传前进行 MIME 校验与大小限制。权限提示:分享触发不需要持久权限,但剪贴板回退需获得用户授权;避免频繁自动复制导致体验问题。日志与监控:仅记录成功/失败的计数与类型,不记录分享内容本身(保护隐私)。验证指标(Chrome 128/Android,PWA 已安装)分享成功率:文本/链接 ≥ 99.5%,图片(≤10MB)≥ 98.5%。分享交互耗时(P95):打开原生分享面板 ≤ 250ms;完成分享 ≤ 2.5s。Share Target 处理耗时(P95):解析 `multipart/form-data` ≤ 120ms;页面打开并呈现 ≤ 600ms。失败占比:用户主动取消 ≥ 95% 的失败原因;权限/类型不匹配 ≤ 0.3%。回退策略与兼容建议iOS/Safari:不支持 Share Target → 使用页面上传入口与剪贴板分享;URL Scheme(如 `mailto:`)作为辅助。桌面端:优先文本/URL分享;文件分享回退至上传组件。无 Service Worker:仅提供 Web Share API;提示用户安装 PWA 以启用接收分享。测试清单功能:文本/URL/文件分享在支持与不支持环境的路径均成功或合理回退。稳定性:连续分享 20 次无崩溃与异常;超大文件正确受限并提示。指标:采集成功率、耗时分布与失败原因分类;隐私检查不含敏感内容。应用场景社交传播、客服转发、媒体素材接力、跨应用内容拾取(系统图库 → PWA 编辑)。

点赞(0) 打赏

评论列表 共有 0 条评论

暂无评论
立即
投稿

微信公众账号

微信扫一扫加关注

发表
评论
返回
顶部