正确做法是用多个source子标签按优先级罗列不同格式,浏览器从上到下加载首个可解码源;每个source必须带准确type属性,如type="audio/mpeg",且首源须为ios支持格式(如mp3),避免因mime不匹配或ios限制导致备用失效。

audio 标签里用多个 source 实现备用播放源
浏览器对音频格式支持不一致,比如 Safari 不支持 opus,老版 IE 只认 wav,单写一个 src 属性很容易直接失败。正确做法是把 audio 当作容器,用多个 source 子标签按优先级罗列不同格式,浏览器会从上到下尝试加载第一个它能解码的。
- 顺序很重要:把兼容性最好、体积适中、主流支持最广的放最前面,比如
mp3;再补上ogg(Firefox/Chrome 早期偏好)、wav(无压缩,兼容老环境但文件大) - 每个
source必须带type属性,值要准确,例如type="audio/mpeg"对应.mp3,type="audio/ogg"对应.ogg或.oga - 不要在
audio标签上写src,否则浏览器可能忽略所有source子元素
<audio controls><source src="song.mp3" type="audio/mpeg"><source src="song.ogg" type="audio/ogg"><source src="song.wav" type="audio/wav"> Your browser does not support the audio element. </source></source></source></audio>
为什么 type 写错会导致备用失效
浏览器不是靠文件后缀判断格式,而是依赖 type 值匹配 MIME 类型。如果写成 type="audio/mp3"(错误)或漏写 type,多数浏览器会跳过该 source,哪怕文件本身完全合法。常见错误类型:
-
audio/mp3→ 应为audio/mpeg -
audio/opus→ 正确,但需确认服务器返回的响应头也匹配,否则仍可能被拒绝 - 省略
type→ Chrome/Firefox 会发起请求但不播放,控制台报Failed to load because no supported source was found
服务器响应头影响 source 是否被采纳
即使 type 写对了,如果服务器返回的 Content-Type 响应头和 type 不一致,部分浏览器(尤其是 Safari)会直接丢弃该源。比如 source 写 type="audio/ogg",但服务器返回 Content-Type: audio/mpeg,Safari 就不认。
- 检查方式:打开开发者工具 → Network → 点击音频请求 → 查看 Response Headers 中的
Content-Type - 静态文件托管(如 GitHub Pages、Nginx)常默认不配音频 MIME 类型,需手动配置,例如 Nginx 加:
types { audio/mpeg mp3; audio/ogg ogg oga; audio/wav wav; } - 本地
file://协议下,浏览器通常忽略响应头,仅依赖type,但这不能代表线上真实行为
移动端 iOS Safari 的特殊限制
iOS 上 audio 元素默认禁止自动播放(包括 autoplay),且必须由用户手势触发播放。但更隐蔽的问题是:iOS Safari 对 source 的预加载策略更激进——它可能只下载第一个 source 的前几 KB 就决定是否支持,若检测失败,不会继续试下一个,直接卡住。
- 避免把
opus放第一位,iOS 目前仍不支持,即使你写了type="audio/opus",它也会停在这里,不往下试 - 确保第一个
source是 iOS 明确支持的格式(mp3、m4a、aac),m4a推荐用type="audio/x-m4a"或audio/mp4 - 不要依赖 JS 动态插入
source后再调用load()—— iOS 要求用户交互后才能开始加载,否则静默失败
source 的强依赖。格式列表写得再全,只要第一个不对路,用户就听不到声音。前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











