speechrecognition.lang 设置无效因浏览器限制:chrome仅支持白名单语言(bcp 47格式如”zh-cn”),需新建实例切换语言;firefox不支持;中文识别依赖网络且无离线模型。

SpeechRecognition.lang 设置后没生效?检查浏览器支持范围
html5 的 SpeechRecognition 接口本身不带语言包,lang 只是向底层语音引擎(如 Chrome 的 Google Speech API)传递提示,实际是否支持取决于浏览器实现和系统环境。Chrome 是目前唯一稳定支持该 API 的主流浏览器,且仅支持它自己白名单里的语言代码。
-
lang必须是 BCP 47 格式,比如"zh-CN"、"en-US"、"ja-JP",写成"zh"或"chinese"会静默失败 - 即使设了
lang = "zh-CN",如果用户设备没装中文语音模型(比如某些海外版 Chrome),识别仍会回退到默认语言(通常是"en-US") - Firefox 完全不支持
SpeechRecognition(只保留实验性webkitSpeechRecognition前缀,且已弃用) - 可运行
navigator.language查看当前浏览器 ui 语言,但这和语音识别语言无关,别混淆
如何验证当前浏览器实际支持哪些语言?
没有标准 API 能枚举可用语言列表,但可以通过快速试探+错误反馈来判断。关键是监听 onError 并注意 Event.error 值:
- 如果报
"no-speech"或"aborted",说明识别启动了,只是没听到有效语音——语言设置大概率没问题 - 如果报
"not-allowed",通常是权限未授或页面非 https(SpeechRecognition强制要求安全上下文) - 如果长时间无响应、
onaudiostart不触发、且onend立即触发,很可能是lang不被支持,引擎直接跳过 - 实操建议:先硬编码
recognition.lang = "en-US"跑通流程,再逐个换目标语言测试
切换语言时必须重启 recognition 实例
SpeechRecognition 实例一旦创建,lang 属性不可动态修改。改了也不生效,必须新建实例。
- 错误写法:
recognition.lang = "ja-JP"; recognition.start();—— 语言不会变 - 正确做法:每次切语言前调用
recognition.abort(),再 new 一个新实例并赋值lang - 注意
abort()不会触发onend,但能确保旧实例彻底停止,避免音频流冲突 - 频繁新建实例不会泄漏内存,但建议复用对象池逻辑,避免反复绑定事件处理器
中文识别不准?重点调 interimResults 和网络环境
中文识别质量远低于英文,不是代码问题,而是底层引擎限制。改善体验的关键不在“换语言包”,而在参数和使用方式:
立即学习“前端免费学习笔记(深入)”;
- 务必设
recognition.interimResults = true,否则中文往往只返回最终结果,错过实时反馈,显得“卡顿” - 识别准确率高度依赖网络延迟和稳定性;国内用户直连 Google 语音 API 几乎必然超时或降级,表现就是
onresult触发极少甚至不触发 - 没有本地离线中文模型;所谓“离线识别”在 Chrome 中对中文完全不可用,
continuous = true也改变不了这点 - 临时缓解:加
recognition.maxAlternatives = 3拿多个候选,再用简单规则(如长度、关键词匹配)做后处理
实际项目里最常被忽略的,是把语言切换当成前端纯配置问题——它本质是跨浏览器、跨网络、跨服务端能力的链路,任何一个环节断掉,lang 就只是个摆设。