必须嵌套在或内,因其仅为不渲染的候选列表,浏览器按序加载首个匹配type的资源;脱离父标签会报domexception且播放器空白,type须与响应头content-type严格一致,路径错误则静默失败。

为什么 <source></source> 必须嵌套在 <audio></audio> 或 <video></video> 里
因为 <source></source> 本身不渲染、不播放,只是“候选列表”。浏览器按顺序读取它,遇到第一个支持的 type 就加载并停止解析。如果把它写在外部、漏掉父标签、或放在 顶层,控制台会报 DOMException: The element has no supported sources,播放器区域直接空白。
常见错误现象:
-
<source src="a.mp3" type="audio/mpeg"></source>单独写在页面中 → 无任何提示,但播放器不出现 - 把多个
<source></source>放在<div> 里再包一层 <code><audio></audio>→ 父标签结构错乱,同样报错正确写法只有一种:必须严格位于
<audio></audio>或<video></video>的开始与结束标签之间,且是其直接子元素。type属性必须和服务器返回的Content-Type严格一致浏览器不是靠文件后缀判断格式,而是比对
type值和 HTTP 响应头中的Content-Type。哪怕只差一个字符(比如audio/mp3vsaudio/mpeg),部分 Safari 版本就会跳过该<source></source>,转而尝试下一个——如果全都不匹配,就静默失败。实操建议:
- 用开发者工具 Network 面板确认每个音频/视频资源的响应头,重点看
Content-Type - MP3 文件对应
type="audio/mpeg",不是audio/mp3;OGG 容器通常用audio/ogg,但若含 Opus 编码,部分浏览器要求audio/opus - 本地开发时用
file://协议,type会被忽略,所有<source></source>都失效 —— 必须走 HTTP(S) 服务
src路径出错时浏览器不会报错,只会静默跳过路径 404、权限拒绝、跨域限制,都不会触发控制台错误,也不会显示 fallback 文本(比如 “您的浏览器不支持 audio 元素”)。你只会看到一个空的播放器控件,或者干脆没控件。
排查方法:
- 逐个检查每个
<source></source>的src是否能单独在新标签页打开并下载 - Network 面板里过滤
media或按状态码筛选4xx/5xx - 确保路径区分大小写(尤其 Linux 服务器上
song.MP3≠song.mp3)
相对路径以当前 HTML 文件为基准,不是以 JS 或 CSS 文件位置为准。
多个
<source></source>的加载顺序和兼容性取舍浏览器从上到下依次检查
<source></source>,一旦匹配就加载第一个,其余全部忽略。所以要把最通用、兼容性最好的格式放最前面(如 MP3),再放更现代但支持率稍低的(如 OGG、AAC、Opus)。典型排序建议:
- 音频:
<source src="a.mp3" type="audio/mpeg"></source>(Chrome/Firefox/Safari/Edge 全支持) - 然后可选:
<source src="a.ogg" type="audio/ogg"></source>(Firefox/Chrome 支持,Safari 旧版不支持) - 再可选:
<source src="a.opus" type="audio/opus"></source>(体积小、音质好,但 Safari 直到 16.4 才支持)
不要为了“未来兼容”把 Opus 放第一位,否则 Safari 用户永远卡在第一项失败,根本不会往下试。
- 用开发者工具 Network 面板确认每个音频/视频资源的响应头,重点看











