share target post 请求体为 multipart/form-data 格式,字段名由 manifest 中 params.files[0].name 显式指定(如 my_file),文件以二进制 part 形式传输,服务端需用 multer 等专用中间件解析,前端 js 无法访问原始文件。

Share Target POST 请求体结构是什么样的
浏览器通过 Web Share Target API 向你的 HTML 页面发起的 POST 请求,不是传统表单提交的 application/x-www-form-urlencoded,也不是纯 JSON;而是 multipart/form-data,且字段名由 Web App Manifest 中定义的 name 决定。
例如你在 manifest.webmanifest 里写了:
{
"share_target": {
"action": "/share",
"method": "POST",
"enctype": "multipart/form-data",
"params": {
"files": [{
"name": "my_file",
"accept": ["image/*", ".pdf"]
}]
}
}
}
那么实际收到的请求中,文件会作为 multipart/form-data 的一个 part,字段名就是 my_file(不是 files,也不是 file)。
- 如果你没在
params.files里指定name,浏览器可能用默认名(如file),但行为不一致,必须显式声明 -
enctype必须设为multipart/form-data,否则浏览器不会发送二进制内容 - Chrome 和 Edge 支持该字段;Safari 尚未支持 Web Share Target,所以这个流程只适用于 Android + Chrome/Edge 或桌面 PWA 场景
后端如何解析 Share Target 的 multipart 文件
你不能靠前端 HTML 表单逻辑处理它——/share 是服务端接收入口,必须由后端解析 multipart body。前端页面(如 /share.html)只是渲染结果,不参与接收。
以 Node.js + Express 为例,你需要:
- 用
multer(而非body-parser)处理multipart/form-data,因为后者只处理 URL 编码和 JSON - 字段名要和 manifest 中
params.files[0].name完全一致,比如是my_file,就要写upload.single('my_file') - 注意:Share Target 可能一次传多个文件,但目前 Chrome 实现中
files数组只支持单个条目,且只上传第一个匹配的文件(即使用户选了多个)
示例中间件:
const upload = multer({ storage: memoryStorage });
app.post('/share', upload.single('my_file'), (req, res) => {
if (!req.file) return res.status(400).send('No file received');
console.log(req.file.originalname, req.file.mimetype, req.file.buffer.length);
// ✅ 此时 req.file.buffer 就是原始二进制数据
});
为什么 fetch 或 FormData 在 Share Target 页面里无法“重新发送”文件
很多人试图在 /share.html 页面 onload 后用 fetch 把文件再 POST 出去,这是行不通的——Share Target 的 POST 请求已经结束,浏览器不会把文件暴露给前端 JS。
原因很直接:
- 浏览器将文件 POST 到你的
/share路由后,服务端响应一个 HTML(比如 200 +/share.html),此时页面加载完成 -
req.file或等价物只存在于服务端 request 生命周期内,前端 JS 拿不到任何文件引用或 Blob -
history.state、location.search、localStorage都不会自动携带文件内容——它们根本没被序列化过
所以,所有业务逻辑(保存、预览、转存)必须在服务端完成,并把结果(如文件 ID、缩略图 URL、JSON 元数据)通过模板变量或内联脚本注入到返回的 HTML 中。
Android 分享到网页时常见的失败原因
即使 manifest 和后端都配对了,仍可能收不到文件,常见断点如下:
-
manifest.webmanifest没有被正确 link 到 HTML:<link rel="manifest" href="/manifest.webmanifest">,且路径需返回Content-Type: application/manifest+json - HTTPS 缺失:Web Share Target 要求站点必须运行在 HTTPS(localhost 除外)
- PWA 未安装:部分 Android 系统(尤其旧版 Chrome)要求应用已“添加到主屏幕”才显示在分享目标列表中
- Accept 类型不匹配:用户分享的是
.docx,但 manifest 里accept只写了["image/*"],则该目标会被过滤掉 - 服务端响应非 2xx:如果
/share返回 302 或 500,Chrome 会静默失败,不报错也不跳转
调试建议:在 /share 处理函数开头加一行日志,确认是否被调用;用 Chrome DevTools 的 Network 面板看是否有对应 POST 请求;检查 Android 设置 → 应用 → Chrome → 权限 → “显示在其他应用上层”是否开启(影响分享菜单渲染)。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











