用web speech api实现点击播报需在用户点击事件中首次调用speechsynthesis.speak(),预热语音列表、指定lang: 'zh-cn'、每次前调用cancel(),并注意浏览器权限、https、系统设置及移动端解锁限制。

怎么用 Web Speech API 实现点击播报文本
现代浏览器原生支持语音合成,不用第三方库就能让页面“开口说话”。核心是 SpeechSynthesis 接口,配合 speechSynthesis.speak() 调用。
常见错误是直接调用 speechSynthesis.speak() 却没等权限就绪,导致静音或报错 DOMException: The user gesture requirement is not met —— 浏览器强制要求必须由用户真实点击(非定时器、非 onload 自动触发)发起第一次播报。
- 必须在用户点击事件回调里首次调用
speechSynthesis.speak() - 首次调用前可先调用
speechSynthesis.getVoices()预热语音列表(但注意:该方法异步,初始返回空数组,需监听voiceschanged事件) - 中文播报推荐显式指定
lang: 'zh-CN',否则可能默认用英文引擎念拼音 - 避免重复调用未暂停的播报:每次点击前建议先执行
speechSynthesis.cancel()清除队列
为什么点了没声音?检查这几点
不是代码写错,大概率是环境或时机问题。
- Chrome / Edge 新标签页首次使用需手动点一次地址栏再点按钮(触发“用户激活”状态),Safari 更严格,仅允许 HTTPS 页面启用
- 系统级禁用了语音服务(如 macOS 的「辅助功能 → 旁白」关闭时,
speechSynthesis.getVoices()可能始终为空) - 传给
SpeechSynthesisUtterance的文本含大量换行、零宽字符或控制符,部分引擎会静默跳过 - 移动端 Chrome Android 有时需要先播放过音频(哪怕
new Audio().play()空播一次)才能解锁语音合成
如何控制语速、音调和发音人
靠 SpeechSynthesisUtterance 实例的属性,不是全局配置。
立即学习“前端免费学习笔记(深入)”;
-
rate:0.5(慢)到 2(快),默认 1;设 0.8–1.2 更自然,超过 1.4 容易失真 -
pitch:0(低)到 2(高),中文建议 0.8–1.1,太高像机器人 -
voice:必须从speechSynthesis.getVoices()返回列表中选,不能硬写名字;可用find(v => v.lang === 'zh-CN')拿中文默认发音人 - 修改后要重新 new 一个
SpeechSynthesisUtterance,改已有实例属性无效
示例:
const utter = new SpeechSynthesisUtterance('你好,今天天气不错');<br>utter.lang = 'zh-CN';<br>utter.rate = 0.9;<br>utter.pitch = 1.0;<br>speechSynthesis.speak(utter);
兼容性差怎么办?别硬扛
Firefox 支持但默认禁用(需在 about:config 开启 media.webspeech.synth.enabled),Safari 仅支持 macOS 且需系统开启“听写”;iOS Safari 基本不可用。
如果项目必须覆盖弱支持环境,别试图 polyfill Web Speech,而是降级为:提供文字转 MP3 的后端接口(用 Python + gTTS 或 Edge TTS),前端生成 <audio></audio> 标签播放。这样可控、稳定、无权限陷阱。
真正难的不是写那几行 speechSynthesis.speak(),而是判断什么时候该放弃原生 API,切到备用链路 —— 这个决策点,比语法细节重要得多。











