PWA接收外部分享需通过manifest.json的share_target字段声明并配合服务端POST路由实现,缺一不可;未安装、非HTTPS、scope越界或字段拼写错误均会导致分享目标注册失败且无提示。
navigator.share 是用来“发”内容的,而接收分享必须靠 Share Target API —— 它不是 JavaScript API,而是通过 Web App Manifest 的 share_target 字段声明 + 服务端路由配合实现的。不配 manifest、不处理 POST 请求,PWA 永远收不到外部应用传来的数据。
share_target 结构浏览器只认 manifest 里的声明,JS 层完全不参与注册过程。常见错误是字段名拼错(比如写成 shareTarget 或 share-target),或漏掉必填字段。
action:必须是相对路径(如 /share),且该路径要能响应 POST 请求;不能是绝对 URL 或带查询参数的路径method:只能是 POST;设成 GET 会静默失败enctype:若要接收文件,必须设为 multipart/form-data;仅传文本/链接时可省略(默认 application/x-www-form-urlencoded)params:必须包含 title、text、url、files 中至少一个键,且键名要和实际提交字段一致示例正确配置:
{ "share_target": { "action": "/share", "method": "POST", "enctype": "multipart/form-data", "params": { "title": "title", "text": "text", "url": "url", "files": ["file"] } }}
操作系统在调用 Share Target 时,会根据内容类型自动选择编码方式:纯文本走 application/x-www-form-urlencoded,含文件走 multipart/form-data,而某些安卓厂商定制系统可能用 application/json(虽非标准但真实存在)。只支持一种格式的服务端大概率收不到部分设备的分享。
application/x-www-form-urlencoded 时,检查 req.body.title、req.body.text 等字段multipart/form-data 时,用 busboy 或 multer 解析 file 字段(注意 manifest 中 files 数组里写的字段名就是表单字段名)application/json,直接 JSON.parse(req.body),结构通常为 { title, text, url, files: [...] }
Node.js Express 示例片段(需 multer 和 body-parser):
app.post('/share', upload.fields([{ name: 'file', maxCount: 10 }]), (req, res) => { const title = req.body.title || ''; const text = req.body.text || ''; const url = req.body.url || ''; const files = req.files?.file || []; // 处理逻辑...});
即使 manifest 配得完全正确,如果用户没把 PWA “添加到主屏幕” 或没完成安装流程(即没触发 beforeinstallprompt 并调用 prompt()),Share Target 不会被系统识别。这不是 bug,是规范强制行为 —— 只有已安装的 PWA 才能注册为系统级分享目标。
navigator.share 会成功,但反过来——其他 App 尝试分享给你的 PWA——会直接跳过它,不会报错也不会提示display: "standalone" 或 "minimal-ui",否则系统不将其视为可分享目标Share Target 要求整个流程都在 HTTPS 下进行,连重定向都不能跳到 HTTP。更隐蔽的问题是作用域(scope)设置:如果 manifest 的 scope 是 /app/,那 share_target.action 就必须在 /app/ 下,比如 /app/share;设成 /share 会导致注册失败且无提示。
Origin 和 Referer,否则某些浏览器会拒绝处理最麻烦的点在于:整个链路没有中间态反馈。manifest 错了、scope 错了、没安装、没 HTTPS、服务端路由 404……所有这些都会表现为“点击分享后,你的 PWA 根本不出现”,而不是弹出错误提示。