直接用 <input type="file"> 配合 FormData + fetch 可上传音频,但需注意 iOS/Android 对 accept 属性、MIME 类型识别及后端字段名匹配的差异;推荐 accept="audio/mpeg,audio/wav,audio/ogg,audio/mp4",字段名必须前后端一致,fetch 上传时切勿手动设置 Content-Type。

直接用 <input type="file"> 配合 FormData + fetch 或 XMLHttpRequest 就能上传,但 iOS 和 Android 对音频文件的识别、accept 属性行为、以及后端字段名匹配稍有差异,不注意容易 400 或收不到文件。
audio/* 与具体 MIME 类型怎么选
浏览器对 accept="audio/*" 的实际过滤很宽松,可能放行 .aac、.m4a 等非标准扩展名,但部分安卓 WebView 会忽略它;iOS Safari 则更倾向只显示系统认可的录音格式(如 .m4a、.wav)。
- 推荐写法:
accept="audio/mpeg,audio/wav,audio/ogg,audio/mp4"—— 明确限定常见可播格式,避免用户误选不可解析文件 - 不要只写
accept="audio/mp3":MP3 的标准 MIME 是audio/mpeg,写错会导致某些浏览器不触发文件选择器 - 服务端必须校验实际
Content-Type和文件头,不能只信前端accept
FormData.append() 的字段名必须和服务端一致
后端框架(如 Express + multer、Python Flask、PHP $_FILES)靠字段名定位上传文件。如果前端写 formData.append('audio', file),后端就必须用 audio 去取,否则返回空或报错。
- 常见错误:前端用
'uploaded_audio',后端却按'audio'解析 → 收不到文件 - 多文件场景下,别用
append('audio', file1); append('audio', file2),而应确保后端支持数组接收(如 multer 的upload.array('audio')) - 上传前可打印
file.type,确认是否为预期值(例如 iOS 录音常返回audio/x-m4a,不是audio/mp4)
fetch 上传时千万别手动设置 Content-Type
用 FormData 提交时,浏览器会自动生成带 boundary 的 multipart/form-data 头。一旦你手动加 headers: { 'Content-Type': 'multipart/form-data' },后端(尤其是 Node.js multer、Java Spring MultipartResolver)会直接丢弃整个 body。
文章转信息图。将文章/笔记转化为手机可读的 HTML 信息图,自动匹配视觉风格。触发场景:文章转图、笔记转图、信息图、转小红书图、做张图、可视化这篇文章、文生图。
立即学习“前端免费学习笔记(深入)”;
- 正确做法:完全不设
headers,让 fetch 自动处理 - 错误示例:
fetch('/upload', { method: 'POST', headers: { 'Content-Type': 'multipart/form-data' }, body: formData })→ 后端收不到文件 - 调试技巧:Chrome DevTools Network 标签页里点请求 → Headers → 检查 Request Headers 是否含
Content-Type: multipart/form-data; boundary=----...,且没有重复设置
iOS H5 上传录音文件的特殊处理
iOS Safari 默认录音保存为 .m4a,但部分老版本返回的 file.type 是空字符串或 '',导致后端无法按类型路由;同时,用户从“语音备忘录”分享进 H5 时,文件名可能含中文或空格,需额外清理。
- 稳妥做法:上传前检查
file.type || 'audio/mp4',并用encodeURIComponent(file.name)处理文件名(后端再 decode) - 避免用
file.name直接拼路径,否则 Linux 服务器可能因编码问题报错 - 真机测试必做:用 iOS 自带“语音备忘录”录一段,通过“分享→在 Safari 中打开”路径上传,验证全流程
最易被忽略的是字段名和服务端约定的严格一致性,以及 fetch 下手设 Content-Type 导致静默失败——这两点没踩过坑的人,往往要花半小时抓包才能定位。


















