React中Axios发送PUT请求FormData无数据,PHP返回error求助
解决Axios发送FormData的PUT请求在PHP后端报错的问题
PHP 默认仅自动解析 POST 请求中的 multipart/form-data 数据,并填充到 $_POST 和 $_FILES 全局变量中,但PUT 请求的 FormData 不会被自动处理——这就是你 POST 正常、PUT 报错的核心原因。
解决方案:手动解析PUT请求的FormData
需要读取请求的原始输入流 php://input,并自行解析其中的 FormData 内容。以下是完整的解析实现:
function parsePutFormData() { $rawInput = file_get_contents('php://input'); if (empty($rawInput)) return ['fields' => [], 'files' => []]; // 获取分隔符(boundary) $boundary = substr($rawInput, 0, strpos($rawInput, "\r\n")); if (!$boundary) return ['fields' => [], 'files' => []]; // 分割各个表单部分 $parts = array_slice(explode($boundary, $rawInput), 1); $fields = []; $files = []; foreach ($parts as $part) { if (trim($part) === '--') break; // 分离头部与内容体 list($rawHeaders, $body) = explode("\r\n\r\n", $part, 2); $body = rtrim($body, "\r\n--"); $headers = []; // 解析头部信息 foreach (explode("\r\n", $rawHeaders) as $headerLine) { list($key, $value) = explode(':', $headerLine, 2); $headers[strtolower(trim($key))] = trim($value); } // 解析Content-Disposition中的字段名 if (!preg_match('/name="([^"]+)"/', $headers['content-disposition'], $fieldMatch)) continue; $fieldName = $fieldMatch[1]; // 判断是普通字段还是文件 if (isset($headers['content-type'])) { // 处理上传文件 preg_match('/filename="([^"]+)"/', $headers['content-disposition'], $fileNameMatch); $fileName = $fileNameMatch[1] ?? 'unknown_file'; // 创建临时文件存储上传内容 $tempPath = tempnam(sys_get_temp_dir(), 'PUT_UPLOAD_'); file_put_contents($tempPath, $body); $files[$fieldName] = [ 'name' => $fileName, 'tmp_name' => $tempPath, 'size' => filesize($tempPath), 'type' => $headers['content-type'], 'error' => UPLOAD_ERR_OK ]; } else { // 处理普通表单字段 $fields[$fieldName] = trim($body); } } return ['fields' => $fields, 'files' => $files]; } // 使用示例 $putData = parsePutFormData(); $formFields = $putData['fields']; // 对应POST请求的$_POST $uploadedFiles = $putData['files']; // 对应POST请求的$_FILES // 后续业务逻辑示例 if (!empty($uploadedFiles['file'])) { $targetPath = '/path/to/save/' . $uploadedFiles['file']['name']; move_uploaded_file($uploadedFiles['file']['tmp_name'], $targetPath); } // 返回成功响应 echo json_encode(['message' => 'success']);
前端确认(可选)
你的Axios请求无需额外修改,因为FormData会自动触发Axios设置正确的multipart/form-data请求头,但如果之前手动设置了错误的头,可以调整为:
const formData = new FormData(); formData.append('file', fileRef.current.files[0]); formData.append('desc', '文件描述'); axios.put('/your-api-endpoint', formData) .then(res => console.log(res.data)) .catch(err => console.error(err));
额外排查点
- 服务器是否允许PUT方法:检查Apache/Nginx配置,确保PUT请求未被拦截(比如Apache的
LimitExcept指令、Nginx的allow规则)。 - 临时文件夹权限:确保
sys_get_temp_dir()返回的目录有写入权限,否则无法创建临时文件存储上传内容。
内容的提问来源于stack exchange,提问作者mermaid
相关产品推荐
相关产品推荐

