PWA 分享集成需要 Service Worker 工作流,而不是只有一个 manifest 条目
单靠manifest 里的 share_target 成员无法让 PWA 成为可靠的分享目标。你需要 service worker、HTTP 方法选择和文件处理,才能交付用户预期的体验。
系统分享对话框是现代操作系统中用户在应用之间传递内容的主要方式。当你的 PWA 出现在那里时,它就加入了用户的日常工作流——但仅靠 manifest 条目无法交付可靠的分享体验。
为什么这件事重要
当分享目标应用打开了,但没有收到分享内容、显示错误,或者要求用户手动粘贴他们以为会自动传递的内容时,分享体验就会让人觉得坏掉了。用户对失效的分享流的反应和失效的网页链接一样:试一次,然后卸载。
MDN Web App Manifest 的 share_target 成员启用了这种集成,但它有三个容易被 PWA 构建者忽视的条件和坑:
- 只有已安装的 PWA 才能作为分享目标——浏览器和 OS 会从分享对话框中过滤掉未安装的应用,不管 manifest 配置得多完善。
- HTTP 方法选择很重要——GET 通过 URL 查询参数传递数据,但 POST 加上
multipart/form-data是文件分享和状态修改操作(如保存书签)的必须选择。 - Service worker 拦截是可靠路径——POST 请求不会自动到达客户端 JavaScript,依赖服务端处理会让离线用户没分享可用。
分享集成检查清单
在推广"分享到我们的 PWA"这个功能之前,先测试这些场景:
- [ ] 安装要求:你的 PWA 必须在分享来源设备上已安装;卸载后确认它从分享对话框中消失。
- [ ] GET vs POST 决策:简单数据(title、text、URL)用 GET,文件上传或状态修改操作(书签、数据库写入)用 POST。
- [ ] 方法对齐:如果用 POST,
enctype必须是"multipart/form-data"才能支持文件分享。 - [ ] Service worker 拦截:添加 fetch 事件监听器来处理 POST 分享请求,并用 HTTP 303 重定向到可显示 URL,避免页面刷新时重复提交。
- [ ] 文件接受:定义
accept数组时同时包含 MIME 类型("text/csv")和扩展名(".csv"),因为不同 OS 平台的偏好不同。 - [ ] 表单字段名:将 manifest 的
params键映射到查询参数名(GET)或表单字段名(POST);通过一次真实分享测试验证。 - [ ] 离线路径:要么在 service worker 中镜像服务端 POST 处理,要么将分享的文件写入 Cache/IndexedDB 并通过
Client.postMessage()通知客户端。 - [ ] 验证:将所有传入的分享数据视为不可信;使用前验证 URL、净化文本,拒绝畸形文件类型。
对安装转化意味着什么
分享对话框是系统级发现界面。当你的 PWA 安装后出现在那里时,它就和用户信任能可靠处理分享内容的原生应用并肩亮相。如果你的分享 integration 失效——内容缺失、静默报错,或提示用户"自己粘贴进来"——你就失去了一个很难重建的信任信号。
从市场评审角度看,引用了无效 action、缺少 params 或没有 service worker 处理 POST 端点的 share_target 条目都应该被标记为不完整。条目存在,但流程不存在。
要避免什么
如果你的 PWA 没安装、无法处理数据或没有验证输入,不要为了满足 PWA 检查清单就加一个 share_target manifest 条目。系统对话框里有一个死掉的分享入口,比没有入口更糟糕。
下一步
阅读完整的 MDN share_target 指南,了解安全和离线相关考虑。不要在没有至少两个 OS 平台——Android 和桌面——的真实安装测试的情况下发布分享集成。