RecorderJS录制WAV后携文件名POST至PHP服务器提交异常问题排查
解决RecorderJS录制WAV后POST提交Blob与自定义文件名到PHP无法识别的问题
我帮你梳理一下这个问题的解法,大概率是前端提交格式或者后端接收逻辑出了问题,咱们一步步来:
一、前端正确构造请求(关键!)
RecorderJS生成的是Blob对象,要同时发送Blob和自定义文件名,必须用FormData来封装数据——直接发JSON是传不了二进制Blob的,而且浏览器会自动帮你设置正确的multipart/form-data请求头,不用手动指定。
示例代码:
// 假设你已经通过RecorderJS完成录制,拿到了音频Blob const audioBlob = recorder.getBlob(); const formData = new FormData(); // 添加自定义文件名到FormData formData.append('custom_filename', 'my-recording-2024.wav'); // 添加音频Blob,第三个参数是浏览器传给服务器的临时文件名(后端可以忽略,用你自定义的就行) formData.append('audio_file', audioBlob, 'temp-audio.wav'); // 发送POST请求 fetch('your-save-script.php', { method: 'POST', body: formData }) .then(res => res.text()) .then(msg => console.log('服务器响应:', msg)) .catch(err => console.error('请求失败:', err));
二、后端PHP正确接收数据
PHP里,文件上传的内容存在$_FILES超全局变量里,而自定义文件名是在$_POST里,别搞混了!另外要注意权限和上传错误检查:
示例代码:
<?php // 先调试看看服务器到底收到了什么(可以先打开这个调试,确认数据是否到达) // echo "<pre>"; print_r($_POST); print_r($_FILES); echo "</pre>"; exit; // 检查必要参数是否存在 if (!isset($_POST['custom_filename']) || !isset($_FILES['audio_file'])) { echo "错误:未接收到文件名或音频文件"; exit; } $customName = $_POST['custom_filename']; $uploadedFile = $_FILES['audio_file']; // 检查上传是否成功(没有错误) if ($uploadedFile['error'] !== UPLOAD_ERR_OK) { echo "上传错误,错误码:" . $uploadedFile['error']; exit; } // 处理保存路径(确保uploads文件夹存在且有写入权限) $saveDir = './uploads/'; if (!is_dir($saveDir)) { mkdir($saveDir, 0755, true); // 递归创建文件夹 } $savePath = $saveDir . $customName; // 移动临时文件到目标路径 if (move_uploaded_file($uploadedFile['tmp_name'], $savePath)) { echo "文件保存成功!路径:" . $savePath; } else { echo "保存失败:无法移动临时文件"; } ?>
三、常见坑点排查
- 前端没用到FormData:直接用
JSON.stringify发送数据会导致Blob被转成字符串,后端完全识别不了,这是最常见的错误。 - PHP用错了变量:别用
$_POST['audio_file']拿文件,文件永远在$_FILES里! - 服务器文件夹权限不足:确保
uploads文件夹的权限是755(或者给服务器运行用户写入权限),否则move_uploaded_file会失败。 - 自定义文件名有风险:如果文件名是用户输入的,记得做过滤,比如用
basename($customName)防止路径遍历攻击,或者加正则验证只允许合法字符。 - 请求头手动设置了Content-Type:用FormData的时候,不要手动设置
Content-Type: multipart/form-data,浏览器会自动生成带boundary的正确头,手动设置反而会出错。
内容的提问来源于stack exchange,提问作者MHSTHLM
相关产品推荐
相关产品推荐

