使用MediaStreamRecorder.js向Django发送Blob时出现404错误求助
Django音频录制:404错误与Blob接收失败解决方案
问题核心诊断
- 404错误原因:HTML中按钮位于
<form>标签内,点击按钮时触发了表单默认提交行为,而非自定义的Fetch/XHR请求,导致请求路径异常(如出现/record-audio/record-audio/)。 - Blob接收为空原因:直接发送Blob时请求Content-Type不是
multipart/form-data,Django无法识别为文件;同时模型代码存在不存在字段的错误引用。
修正步骤与代码
1. 前端代码修正(阻止默认提交+FormData包装Blob)
function sendData(blob) { const csrf_token = getCookie('csrftoken'); const formData = new FormData(); // 用FormData包装Blob,指定字段名和文件名 formData.append('blob', blob, 'recording.wav'); // 使用Django模板标签生成绝对路径,避免相对路径错误 fetch("{% url 'record_audio' %}", { method: 'POST', headers: { "X-CSRFToken": csrf_token }, body: formData }) .then(response => { if (!response.ok) throw new Error('请求失败'); return response.json(); }) .then(data => console.log(data)) .catch(err => console.error(err)); } // 绑定停止按钮事件,阻止表单默认提交 document.getElementById('stop-recording').addEventListener('click', function(e) { e.preventDefault(); // 这里添加你的停止录制逻辑,获取到Blob后调用sendData sendData(blob); });
同时修改HTML按钮,添加type="button"彻底阻止默认提交:
<form method="post" enctype="multipart/form-data" action="{% url 'record_audio' %}"> {% csrf_token %} <button id="start-recording" type="button">Start</button> <button id="pause-recording" type="button" disabled>Pause</button> <button id="resume-recording" type="button" disabled>Resume</button> <button id="stop-recording" type="button" disabled>Stop</button> </form>
2. 后端views.py修正
from django.shortcuts import render from django.http import HttpResponseBadRequest, JsonResponse from django.views.decorators.csrf import ensure_csrf_cookie from datetime import datetime from .models import AudioFile @ensure_csrf_cookie def record_audio(request): if request.method == 'GET': return render(request, 'recording/record.html') # 从request.FILES获取上传的音频文件 audio_file = request.FILES.get("blob") if not audio_file: return HttpResponseBadRequest("Missing audio file") now = datetime.now().strftime("%Y-%m-%d_%H-%M-%S") filename = f"{request.user.username}_{now}.wav" # 读取文件内容存入BinaryField audio_blob = audio_file.read() audio_obj = AudioFile(name=filename, user=request.user, audio_blob=audio_blob) audio_obj.save() return JsonResponse({'status': 'success'})
3. 模型models.py修正(移除错误字段引用)
from django.db import models from django.contrib.auth.models import User class AudioFile(models.Model): name = models.CharField(max_length=100, null=True) audio_blob = models.BinaryField(null=True, blank=True) user = models.ForeignKey(User, on_delete=models.CASCADE) def save(self, *args, **kwargs): # 移除不存在的self.audio字段引用 super(AudioFile, self).save(*args, **kwargs) class Meta: verbose_name_plural = "Audio Files" def __str__(self): return self.name
内容的提问来源于stack exchange,提问作者lilsnow02
相关产品推荐
相关产品推荐

