You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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));

额外排查点

  1. 服务器是否允许PUT方法:检查Apache/Nginx配置,确保PUT请求未被拦截(比如Apache的LimitExcept指令、Nginx的allow规则)。
  2. 临时文件夹权限:确保sys_get_temp_dir()返回的目录有写入权限,否则无法创建临时文件存储上传内容。

内容的提问来源于stack exchange,提问作者mermaid

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 19:52:49