srclang属性缺失或非法会导致字幕轨道被浏览器静默忽略;它必须存在且符合BCP 47规范(如zh、en),否则video.textTracks不注册、菜单不显示、控制台无报错。

srclang 属性缺失或非法,字幕轨道会被浏览器静默忽略
只要 kind="subtitles",srclang 就不是可选的——它必须存在、且值合法,否则该 <track> 在 Chrome、Firefox、Safari 中均不会进入 video.textTracks 列表,右键菜单里也看不到对应选项,控制台还不会报错。
常见错误现象包括:
-
<track kind="subtitles" src="zh.vtt">—— 缺srclang,直接失效 -
srclang="zh-CN"或srclang="Chinese"—— 非法格式,被跳过 -
srclang=""、srclang=" zh "、srclang="zh_Hans"—— 含空格、下划线、空值,readyState 为 0
正确写法只接受 BCP 47 兼容的两个字母主标签(如 zh、en、ja),大小写不敏感,但惯例全小写;带区域子标签时(如 zh-Hans)也合法,且匹配更精确。
srclang 和 label 必须分工明确,不能混用
srclang 是机器可读的语言标识,用于系统语言匹配、脚本定位、默认启用逻辑;label 是用户可见的菜单名称,纯属 UI 层面。两者语义不同,填错会导致“能看见但切不了”或“能切但不自动匹配”。
立即学习“前端免费学习笔记(深入)”;
典型误配:
-
srclang="zh"+label="English"—— 用户看到英文名,实际是中文轨道,JS 查找时易出错 -
srclang="en-US"+label="中文字幕"—— 系统语言为zh-CN时无法 fallback 匹配 - 多个
srclang="zh"的轨道共存 —— 浏览器通常只加载第一个,其余静默丢弃
推荐搭配:srclang="zh-Hans" 对应 label="中文(简体)",srclang="en" 对应 label="English"。
动态设置 srclang 要避开 setAttribute 陷阱
通过 JS 修改已挂载的 <track> 的 srclang,不能用 setAttribute("srclang", "ja") —— 多数浏览器完全不响应此操作,也不会触发重加载。
安全做法是直接赋值:
trackEl.srclang = "ja";
但要注意时机和兼容性:
- 必须等
video触发loadedmetadata事件后再操作,否则 DOM 已挂载但轨道未注册完成 - IE9 及更早、Safari ≤15.6、部分旧版 Firefox 不支持动态修改,需降级为移除旧
<track>+ 插入新节点 - 即使赋值成功,也不会自动 fetch 新字幕文件 ——
src不变,只是更新语言标识
srclang 正确 ≠ 字幕一定能显示,别漏掉服务端环节
srclang 只管“语言声明”,不管“文件可达”。哪怕所有 HTML 属性都写对了,如果出现以下任一情况,字幕依然空白:
-
src指向的 .vtt 文件返回 HTTP 404 或 403 - 服务端未配置 MIME 类型,返回的不是
text/vtt(Nginx/Apache 需显式添加add_type text/vtt .vtt;) - .vtt 文件本身有 BOM、首行不是
WEBVTT、时间戳毫秒位不是三位(如00:00:01.23 --> 00:00:03.45) - 跨域请求未配 CORS(
Access-Control-Allow-Origin: *),尤其当 video 和 vtt 来自不同域名时
真正容易被忽略的是:浏览器在解析 <track> 时,会先校验 srclang,再发起 src 请求;前者失败,后者根本不会出发 —— 所以排查顺序永远是:srclang → src 可达性 → vtt 格式 → MIME 类型。


















