Laravel中Blob URL音频存储至服务器空文件问题及调试
音频Blob URL存储为空的调试与修复方案
问题描述
我有一个门户系统,录制用户音频后获取到Blob URL,希望将该Blob URL对应的音频文件存储到数据库,但保存的文件为空。以下是我的代码:
JS代码
$('#upload-read-aloud').on('submit',function(e){ e.preventDefault(); $.ajax({ type : 'GET', cache : false, data : {audioUrl:audioUrl}, url : '../upload-read-aloud-test', success:function(response){ alert(response) } }) })
Laravel控制器代码
$url = $req->audioUrl; $upload_dir = public_path()."/assets/"; $audio= $url; $audio= str_replace('data:audio/wav;base64,', '', $audio); $audio = str_replace(' ', '+', $audio); $data = base64_decode($audio); $file = $upload_dir . time() . ".wav"; $success = file_put_contents($file, $data); echo $success ? $file : 'Unable to save the file.';
调试步骤
1. 前端核心问题排查
- Blob URL(格式如
blob:http://xxx/xxxx)是浏览器临时内部URL,不是Base64编码字符串,直接传给后端无法解码出有效音频数据,这是文件为空的根本原因。 - GET请求参数长度有限,即使强行转Base64也可能被截断,导致内容不完整。
- 在AJAX发送前执行
console.log(audioUrl),确认它的实际格式——如果是Blob URL,必须先读取Blob内容再传递。
2. 后端验证
- 在控制器中添加
dd($url),查看实际接收到的参数是否和前端一致。 - 打印
strlen($data),若结果为0,说明解码完全失败,因为Blob URL无法被base64_decode处理。 - 检查
public/assets/目录的写入权限:执行chmod -R 755 public/assets/确保后端有权限写入文件。
修复方案
前端改用FormData发送Blob文件
$('#upload-read-aloud').on('submit',function(e){ e.preventDefault(); // 通过Blob URL获取Blob对象 fetch(audioUrl) .then(res => res.blob()) .then(blob => { const formData = new FormData(); // 将Blob对象加入FormData并指定文件名 formData.append('audio', blob, `recording-${Date.now()}.wav`); $.ajax({ type : 'POST', cache : false, // 必须禁用这两个选项,否则FormData会被错误处理 processData: false, contentType: false, data : formData, url : '../upload-read-aloud-test', success:function(response){ alert(response) } }); }); })
后端接收FormData并存储
use Illuminate\Http\Request; public function uploadReadAloud(Request $request) { $uploadDir = public_path('assets/'); // 确保存储目录存在,不存在则创建 if (!is_dir($uploadDir)) { mkdir($uploadDir, 0755, true); } if ($request->hasFile('audio')) { $audioFile = $request->file('audio'); $fileName = time() . '.' . $audioFile->getClientOriginalExtension(); // 移动文件到目标目录 $audioFile->move($uploadDir, $fileName); // 可在此处将文件路径或内容存入数据库 echo $uploadDir . $fileName; } else { echo '未接收到有效音频文件'; } }
内容的提问来源于stack exchange,提问作者Vinay Munjal
相关产品推荐
相关产品推荐

