如何实现Django通过HttpResponse向Vue传输GTTTS生成的音频文件?
解决Django返回MP3音频给Vue时的乱码问题
Django端优化代码
直接使用Django内置的FileResponse替代HttpResponse,它会自动处理文件的Content-Type、Content-Length,还能避免手动管理文件句柄的问题:
from django.http import FileResponse def get_audio(request): audio_path = 'path/of/mp3/file' return FileResponse(open(audio_path, 'rb'), content_type='audio/mp3')
如果坚持使用HttpResponse,至少要确保文件读取和关闭的正确性:
from django.http import HttpResponse import os def get_audio(request): audio_path = 'path/of/mp3/file' with open(audio_path, 'rb') as f: response = HttpResponse(f.read(), content_type='audio/mp3') response['Content-Length'] = os.path.getsize(audio_path) return response
Vue端正确接收二进制数据
问题核心是请求时未指定响应类型为二进制,导致axios将音频二进制数据错误转成字符串。需要在请求中设置responseType: 'blob',再将Blob转为可播放的URL:
示例代码(axios)
import axios from 'axios' async function fetchAudio() { try { const response = await axios.get('/api/get-audio/', { responseType: 'blob' // 关键:指定响应为Blob类型 }) // 创建可播放的音频URL const audioUrl = URL.createObjectURL(response.data) // 播放音频 const audio = new Audio(audioUrl) audio.play() // 用完后释放URL,避免内存泄漏 audio.onended = () => { URL.revokeObjectURL(audioUrl) } } catch (error) { console.error('获取音频失败:', error) } }
原生fetch实现
async function fetchAudio() { try { const response = await fetch('/api/get-audio/') const blob = await response.blob() const audioUrl = URL.createObjectURL(blob) const audio = new Audio(audioUrl) audio.play() audio.onended = () => URL.revokeObjectURL(audioUrl) } catch (error) { console.error('获取音频失败:', error) } }
为什么之前的Blob方法无效?
因为你接收到的是被转成字符串的二进制数据,此时再转Blob已经损坏了原始字节。必须让请求直接接收Blob类型的响应,才能保留完整的音频数据。
内容的提问来源于stack exchange,提问作者Yoony Lim
相关产品推荐
相关产品推荐

