Django中使用xhr.send(blob)发送音频文件失败求助
Django后端接收音频Blob失败排查与解决
常见问题及修复方案
1. 后端数据处理逻辑不匹配
前端发送Blob的方式不同,后端的处理代码也需对应调整:
场景1:前端直接发送原始Blob
后端需读取请求体原始数据:
# views.py from django.http import JsonResponse def receive_audio(request): if request.method == 'POST': # 读取原始音频二进制数据 audio_data = request.body # 示例:保存到本地文件 with open('received_audio.wav', 'wb') as f: f.write(audio_data) return JsonResponse({'status': 'success'}) return JsonResponse({'status': 'error', 'msg': '仅支持POST请求'}, status=405)
场景2:前端用FormData包装Blob(更推荐,兼容文件上传场景)
后端从request.FILES中获取文件:
# views.py from django.http import JsonResponse def receive_audio(request): if request.method == 'POST': if 'audio' not in request.FILES: return JsonResponse({'status': 'error', 'msg': '未接收音频文件'}, status=400) audio_file = request.FILES['audio'] # 分块保存文件 with open(audio_file.name, 'wb') as f: for chunk in audio_file.chunks(): f.write(chunk) return JsonResponse({'status': 'success'}) return JsonResponse({'status': 'error', 'msg': '仅支持POST请求'}, status=405)
2. 前端请求配置错误
直接发送Blob的正确写法
需指定音频对应的Content-Type,并携带CSRF令牌:
// 假设已获取到audioBlob实例 const xhr = new XMLHttpRequest(); xhr.open('POST', '/receive-audio/', true); // 设置音频类型,根据实际格式调整(如audio/mp3、audio/wav) xhr.setRequestHeader('Content-Type', 'audio/wav'); // 添加CSRF令牌(从页面隐藏元素获取,Django模板需有{% csrf_token %}) const csrfToken = document.querySelector('[name=csrfmiddlewaretoken]').value; xhr.setRequestHeader('X-CSRFToken', csrfToken); xhr.onload = function() { xhr.status === 200 ? console.log('上传成功') : console.error('上传失败:', xhr.responseText); }; xhr.onerror = function() { console.error('请求连接出错'); }; xhr.send(audioBlob);
用FormData包装Blob的正确写法
无需手动设置Content-Type,浏览器会自动处理:
const formData = new FormData(); // 第三个参数是文件名,可自定义 formData.append('audio', audioBlob, 'my_recording.wav'); // 添加CSRF令牌 const csrfToken = document.querySelector('[name=csrfmiddlewaretoken]').value; formData.append('csrfmiddlewaretoken', csrfToken); const xhr = new XMLHttpRequest(); xhr.open('POST', '/receive-audio/', true); xhr.onload = function() { xhr.status === 200 ? console.log('上传成功') : console.error('上传失败:', xhr.responseText); }; xhr.onerror = function() { console.error('请求连接出错'); }; xhr.send(formData);
3. 系统限制与中间件问题
- CSRF拦截:确保请求携带CSRF令牌,否则Django会直接拦截POST请求
- 文件大小限制:若音频文件过大,需在
settings.py中调整参数:
# settings.py # 允许的最大内存上传文件大小(示例为10MB) FILE_UPLOAD_MAX_MEMORY_SIZE = 10 * 1024 * 1024 DATA_UPLOAD_MAX_MEMORY_SIZE = 10 * 1024 * 1024
排查步骤
- 打开浏览器开发者工具的Network面板,查看请求的状态码、请求头、请求体/FormData是否正确
- 后端打印
request.META、request.body或request.FILES,确认数据是否正常到达 - 查看Django运行日志,定位具体报错信息
内容的提问来源于stack exchange,提问作者lilsnow02
相关产品推荐
相关产品推荐

