SpeechRecognition API调用start()后立即触发onend事件问题
这个问题和JS调用写法的关系不大,基本都是环境/配置限制导致的,按以下顺序排查即可:
先确认页面运行在安全上下文
语音识别API只在安全环境下可用,本地调试只能用localhost/127.0.0.1,线上环境必须是https://协议,普通HTTP站点调用API会被浏览器直接拦截,启动即退出。确认站点麦克风权限已开启
点击地址栏左侧的锁形图标,查看麦克风权限是否设置为「允许」,如果是禁止状态,修改后刷新页面重试。给snap版Chromium开放系统麦克风权限
你当前使用的是snap安装的Chromium,沙箱机制默认会拦截应用的麦克风访问,哪怕浏览器内给了站点权限,系统沙箱层没放行的话一样拿不到音频输入,直接在终端执行以下命令赋权,执行完重启浏览器即可:sudo snap connect chromium:audio-record :audio-record这是snap版Chromium上该问题的最高发诱因。
确认网络能连通语音识别服务
Chromium自带的SpeechRecognition默认依赖谷歌在线语音识别接口,如果当前网络无法访问谷歌服务,识别引擎初始化会直接失败退出,没有额外弹窗提示。
如果需要离线可用的语音识别能力,不要用原生API,换本地识别方案即可。补全API配置,绑定错误事件拿具体报错
不要只监听onend事件,必须绑定onerror回调才能拿到具体失败原因,同时补上几个兼容性配置减少异常退出概率,参考写法:const timestamp = Date.now() const speech = new webkitSpeechRecognition() // 持续识别,不会识别到短暂停顿就自动终止 speech.continuous = true // 返回临时识别结果,避免无匹配结果直接退出 speech.interimResults = true // 明确指定识别语言,和系统/页面语言不匹配可能导致初始化失败 speech.lang = 'zh-CN' // 识别英文就改成'en-US' speech.onerror = (e) => console.log('识别报错,错误码:', e.error) speech.onend = () => console.log('ended after', Date.now() - timestamp, 'ms') speech.start()常见错误码对应原因:
not-allowed是麦克风权限被拒、service-not-allowed是网络不通/语音服务不可用、audio-capture是系统麦克风设备异常/被占用。运行日志参考:

排查系统麦克风状态
关闭其他可能占用麦克风的会议/录音软件,到系统声音设置里确认默认麦克风设备选中正确、输入音量不为0,没有被系统静音。
内容的提问来源于stack exchange,提问作者Sharcoux

