通过Echo框架传递Google TTS音频到JS Blob时播放失败问题
解决Go Echo框架传递Google TTS音频到前端的播放问题
问题根源
jQuery默认会将HTTP响应解析为UTF-8字符串,而Google TTS返回的是二进制MP3数据,非UTF-8编码的二进制数据在转字符串过程中会被损坏,导致字节数异常、音频无法解码。Wireshark抓包显示浏览器确实收到了完整数据,但前端解析时被转码破坏。
解决方案
方案1:修正jQuery AJAX配置,以Blob形式接收数据
修改AJAX的xhrFields,设置responseType: 'blob',让浏览器直接以二进制Blob对象接收数据,避免转码:
var options = { url: "/tts", method: "POST", contentType: 'application/json', xhrFields: { responseType: 'blob' // 关键:指定接收Blob类型 }, data: JSON.stringify(data), success: function (response) { console.log(response.size); // 此时应与服务端的5664一致 var blobUrl = URL.createObjectURL(response); var audio = new Audio(blobUrl); audio.addEventListener('loadeddata', function() { audio.play(); }); audio.addEventListener('error', function(event) { console.error('Audio error:', event.target.error.message); }); audio.load(); }, error: function (xhr, status, error) { console.log(status, error) } } $.ajax(options);
方案2:以ArrayBuffer形式接收数据
如果需要操作原始字节,也可以用arraybuffer类型接收,再转为Blob:
var options = { url: "/tts", method: "POST", contentType: 'application/json', xhrFields: { responseType: 'arraybuffer' }, data: JSON.stringify(data), success: function (response) { console.log(response.byteLength); // 应等于服务端的5664 var blob = new Blob([response], { type: 'audio/mp3' }); var blobUrl = URL.createObjectURL(blob); var audio = new Audio(blobUrl); audio.addEventListener('loadeddata', function() { audio.play(); }); audio.addEventListener('error', function(event) { console.error('Audio error:', event.target.error.message); }); audio.load(); }, error: function (xhr, status, error) { console.log(status, error) } } $.ajax(options);
方案3:使用原生XMLHttpRequest(更可靠)
绕开jQuery的默认解析逻辑,直接用原生XHR:
var xhr = new XMLHttpRequest(); xhr.open('POST', '/tts', true); xhr.setRequestHeader('Content-Type', 'application/json'); xhr.responseType = 'blob'; xhr.onload = function() { if (xhr.status === 200) { var blobUrl = URL.createObjectURL(xhr.response); var audio = new Audio(blobUrl); audio.addEventListener('loadeddata', () => audio.play()); audio.addEventListener('error', (event) => { console.error('Audio error:', event.target.error.message); }); audio.load(); } }; xhr.onerror = () => console.log('Request failed'); xhr.send(JSON.stringify(data));
验证要点
- 前端打印的
response.size(Blob)或response.byteLength(ArrayBuffer)应与服务端的5664一致 - 音频加载后无DEMUXER_ERROR报错,可正常播放
内容的提问来源于stack exchange,提问作者MikaAll
相关产品推荐
相关产品推荐

