Laravel项目音频录制存储数据库及无Ajax提交Blob问题
不使用Ajax提交录制的Blob音频文件(Laravel环境)
方法1:隐藏文件输入框+普通表单提交
- 将Blob转为File对象
录制完成后,把Blob封装成带文件名的File实例:// 假设recordedBlob是你录制得到的Blob对象 const audioFile = new File([recordedBlob], 'recording.wav', { type: 'audio/wav' }); - 创建隐藏的file输入元素并赋值
动态生成一个不可见的文件输入框,把File对象传入:const fileInput = document.createElement('input'); fileInput.type = 'file'; fileInput.name = 'audio_file'; // 对应后端接收的字段名 fileInput.style.display = 'none'; // 用DataTransfer把File对象放入输入框的文件列表 const dataTransfer = new DataTransfer(); dataTransfer.items.add(audioFile); fileInput.files = dataTransfer.files; document.body.appendChild(fileInput); - 关联表单并提交
把隐藏输入框加入现有表单,触发提交:const form = document.getElementById('audio-form'); // 你的表单ID form.appendChild(fileInput); form.submit();
方法2:构建FormData+临时表单提交
如果不想依赖现有表单,可以直接生成临时表单提交:
// 转Blob为File const audioFile = new File([recordedBlob], 'recording.mp3', { type: 'audio/mpeg' }); // 构建FormData,可附加其他字段 const formData = new FormData(); formData.append('audio_file', audioFile); formData.append('user_id', '{{ auth()->id() }}'); // Laravel模板直接取登录用户ID // 创建临时表单 const form = document.createElement('form'); form.method = 'POST'; form.action = '{{ route("audio.store") }}'; // 替换为你的Laravel存储路由 // 加入CSRF令牌(Laravel必填) const csrfInput = document.createElement('input'); csrfInput.type = 'hidden'; csrfInput.name = '_token'; csrfInput.value = '{{ csrf_token() }}'; form.appendChild(csrfInput); // 将FormData内容转为表单输入项 for (const [key, value] of formData.entries()) { const input = document.createElement('input'); input.type = 'hidden'; input.name = key; input.value = value; form.appendChild(input); } // 提交表单 document.body.appendChild(form); form.submit();
Laravel后端接收与存储示例
在routes/web.php中定义路由:
use Illuminate\Http\Request; use Illuminate\Support\Facades\Storage; Route::post('/audio/store', function(Request $request) { // 验证文件规则 $request->validate([ 'audio_file' => 'required|file|mimes:wav,mp3|max:10240', // 限制10M以内 ]); if ($request->hasFile('audio_file')) { $file = $request->file('audio_file'); // 存储到storage/app/public/audio目录,生成唯一文件名避免重复 $fileName = uniqid() . '.' . $file->getClientOriginalExtension(); $path = Storage::putFileAs('audio', $file, $fileName, 'public'); // 将文件路径存入数据库(假设你有Audio模型) \App\Models\Audio::create([ 'user_id' => $request->user_id, 'file_path' => $path, 'original_name' => $file->getClientOriginalName(), ]); return redirect()->back()->with('success', '音频存储成功'); } return redirect()->back()->with('error', '音频存储失败'); })->name('audio.store');
关键注意点
- 必须携带Laravel的CSRF令牌,否则后端会拒绝请求
- Blob转File时要指定正确的MIME类型,和后端验证规则保持一致
- 若需要公开访问音频文件,记得执行
php artisan storage:link生成软链接
内容的提问来源于stack exchange,提问作者Bilal Zahid
相关产品推荐
相关产品推荐

