share_target 必须严格按 android intent filter 语义配置:action 为相对路径(如"./share"),method 仅支持"post",enctype 必须是"multipart/form-data",params 中字段需与 sw/页面处理逻辑一致,否则浏览器直接忽略。

share_target 在 manifest.json 里怎么配才生效
不配对或漏字段,share_target 直接被浏览器忽略,分享时根本不会弹出你的 PWA。关键不是“写了就行”,而是字段必须严格匹配 Android Intent Filter 的语义,且只在支持 Web Share Target 的浏览器中起作用(Chrome 76+、Edge 90+,Safari 不支持)。
常见错误:action 写成绝对路径但没加 / 开头;method 写成 GET 却试图接收文件;enctype 漏掉或写错成 multipart/form-data(实际只接受 multipart/form-data,但 manifest 里必须写成 multipart/form-data —— 注意引号和大小写)。
-
action必须是相对路径(如"./share"),且该路径需能被 Service Worker 拦截并响应 -
method只能是"POST"(规范强制要求,GET会被忽略) -
enctype必须是"multipart/form-data"(字符串字面量,大小写敏感) -
params中的title、text、url、files都是可选,但一旦声明,就必须在后续 HTML 表单或 SW 处理中对应上
示例正确片段:
{
"share_target": {
"action": "./share",
"method": "POST",
"enctype": "multipart/form-data",
"params": {
"title": "title",
"text": "text",
"url": "url",
"files": [{
"name": "my-file",
"accept": ["image/*", ".pdf"]
}]
}
}
}
Service Worker 怎么拦截并解析 share_target POST 请求
浏览器在用户从系统分享菜单选择你的 PWA 后,会向 manifest.json 中声明的 action 路径发起一个 POST 请求,这个请求**不会走常规 fetch 事件的页面上下文**,而是由 Service Worker 的 fetch 事件捕获 —— 所以你不能靠页面 JS 直接收,必须用 SW。
难点在于:这个请求是 multipart/form-data,而 Request.formData() 在 SW 环境中**部分浏览器不支持解析文件字段**(尤其是 Chrome 旧版本)。稳妥做法是用 Request.arrayBuffer() + 手动解析 multipart body,但更实用的是:只收文本字段(title/text/url),把 files 声明为可选,并在页面里用 navigator.share() 回退逻辑兜底。
- 在 SW 的
fetch事件中,先用event.request.url.endsWith('/share')判断是否为目标请求 - 调用
event.request.formData()—— 如果返回 Promise resolve,说明文本字段可用;若 reject 或返回空对象,说明只有文件或解析失败 - 不要尝试在 SW 里读取
File对象(它没有arrayBuffer()方法),应重定向到页面 URL 并附带 query 参数(如?share_title=xxx&share_text=yyy),再由页面 JS 处理 - 务必在 SW 中
event.respondWith()返回一个有效的 HTML 响应(哪怕只是OK),否则 Android 会报“应用无响应”
HTML 页面如何接收并展示分享来的数据
Service Worker 解析完后,通常会跳转到一个页面(比如 /share?title=xxx&text=yyy),这时页面 JS 就要从 URL 参数或 localStorage(SW 写入)里取值。注意:不能依赖 document.referrer,因为来源是系统分享面板,不是网页跳转。
容易被忽略的一点:Android 分享目标页首次加载时,PWA 可能尚未完全激活(比如 SW 还在 install 中),导致页面 JS 执行早于 SW 数据写入。所以得加轮询或用 postMessage 从 SW 主动推送。
- 页面加载后立即检查 URL searchParams,提取
title、text、url - 如果没拿到,监听
navigator.serviceWorker.addEventListener('message', ...),等待 SW 发送数据 - 避免直接
document.write或 innerHTML 注入未过滤的text,防止 XSS(尤其当text来自第三方 App) - 如果需要处理图片,建议让 SW 把文件转成 data URL 后通过
postMessage发送,而不是传二进制 blob(跨线程限制)
调试 share_target 最有效的三个方法
大部分问题出在“以为配了就能用”,结果分享菜单里压根不显示你的 PWA,或者点了之后白屏/404/无反应。真正在现场调试,别信文档,信 Chrome 的 DevTools 和 Android 日志。
- 在 Chrome for Android 打开
chrome://inspect→ 连上设备 → 找到你的 PWA 标签页,勾选Discover USB devices,然后在“Service Workers”里看是否注册成功、是否有 unhandled rejection - 分享时打开 Chrome 的 Network 面板(需提前开启),观察是否发出了 POST 到
/share,状态码是不是 200,响应体是否为 HTML - 在 Android 设置 → 应用 → Chrome → 存储 → 清除缓存(不是清除数据),因为 manifest 更新后,Chrome 有时会缓存旧的 share_target 配置,重启 Chrome 也不生效,必须清缓存
真正麻烦的永远不是配置本身,而是 Android 分享面板的 Intent 匹配规则 —— 它会根据你声明的 accept 类型、设备当前分享内容的实际 MIME type、甚至系统语言做隐式过滤。哪怕 accept: ["image/*"],遇到某些厂商定制 ROM 的图库,也可能不出现你的图标。这种时候,只能降级用 text + url 组合保底。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











