如何用ExpressJS从外部URL获取音频并通过API返回可播放音频?
解决音频端点返回乱码并可直接播放的问题
问题根源
- Axios默认会把响应数据解析为字符串(
responseType默认是json),二进制音频数据被转成UTF-8字符串后损坏,导致浏览器显示乱码。 - 未给响应设置正确的
Content-Type头,浏览器无法识别这是音频文件,自然无法触发播放逻辑。
修复步骤及代码
1. 修改Axios请求,获取二进制原始数据
将Axios的responseType设为arraybuffer,确保拿到未被篡改的二进制音频数据:
async function getData(url: string) { // 直接返回Axios的Promise,无需额外包装Promise return axios.get(url, { responseType: 'arraybuffer' // 关键配置:获取二进制数组 }); }
2. 正确返回音频响应
在接口中设置匹配音频格式的Content-Type头(比如MP3用audio/mpeg,WAV用audio/wav),并将二进制数据发送给浏览器:
app.get('/audio', async (req: Request, res: Response) => { try { const resp = await getData('external_url'); // 设置音频类型响应头,根据实际格式调整 res.setHeader('Content-Type', 'audio/mpeg'); // 直接发送二进制原始数据 res.status(200).send(resp.data); } catch (error) { res.status(500).send('获取音频失败'); } });
额外优化
可以直接复用外部接口返回的Content-Type,避免手动指定错误:
app.get('/audio', async (req: Request, res: Response) => { try { const resp = await getData('external_url'); // 优先用外部接口的Content-Type,兜底设为MP3格式 const contentType = resp.headers['content-type'] || 'audio/mpeg'; res.setHeader('Content-Type', contentType); res.status(200).send(resp.data); } catch (error) { res.status(500).send('获取音频失败'); } });
内容的提问来源于stack exchange,提问作者Oğuz Öztınaz
相关产品推荐
相关产品推荐

