React多文件上传至PHP:无法在$_FILES获取文件的解决方法
解决React上传文件后PHP无法通过
$_FILES获取的问题 我看到你遇到的问题了——前端上传的文件没有出现在PHP的$_FILES里,反而以[object File]的字符串形式跑到$_POST["imgs"]中,这是因为前端的FormData处理和请求头设置出了两个关键问题,咱们一步步来修复:
问题根源
- 错误的FormData添加方式:你直接把整个
acceptedFiles数组传给了formData.append('imgs', acceptedFiles),FormData无法正确解析数组里的文件对象,只会把数组转成字符串[object File]发送。 - 手动设置错误的请求头:你手动指定了
Content-Type: mulipart/form-data(还拼错了单词,正确写法是multipart),但axios在处理FormData时会自动生成包含边界标识的正确Content-Type,手动设置反而会丢失这个关键的边界信息,导致后端无法识别文件部分。
修复步骤及修改后的代码
1. 正确添加文件到FormData
循环acceptedFiles数组,逐个将文件添加到FormData中,这样每个文件都会被正确识别:
const formData = new FormData() acceptedFiles.forEach(file => { formData.append('imgs[]', file, file.name) // 用imgs[]让PHP识别为数组,第三个参数可选,用于指定文件名 })
这里用imgs[]作为key是为了让PHP能把多个文件解析到$_FILES['imgs']数组里,如果你只传单个文件,也可以直接用imgs。
2. 移除手动设置的Content-Type
不管是axios实例创建时的headers,还是post请求时的headers,都删掉手动设置的Content-Type,让axios自动处理:
修改后的完整组件代码:
import React, { useCallback } from 'react' import { useDropzone } from 'react-dropzone' import axios from 'axios' // 创建axios实例时不要手动设置Content-Type const imgAjaxUploader = axios.create({ baseURL: 'http://localhost', timeout: 1000 }); export default function ImgDropzone() { const onDrop = useCallback(acceptedFiles => { const formData = new FormData() // 循环添加每个文件到FormData acceptedFiles.forEach(file => { formData.append('imgs[]', file, file.name) }) try { // post请求时也不要手动设置Content-Type imgAjaxUploader.post('/store/admin/imgHandler.php', formData) .then(data => console.log(data)) .catch(err => { console.log(err) return null }) } catch (err) { alert(err) } }, []) const { getRootProps, getInputProps, isDragActive } = useDropzone({ onDrop: onDrop, accept: 'image/jpeg, image/png' }) return ( <div {...getRootProps()} style={{ display: "inline-block" }}> <input {...getInputProps()} /> { isDragActive ? <p>Drop the files here ...</p> : <p>Drag 'n' drop some files here, or click to select files</p> } </div> ) }
PHP端接收示例
现在你可以在imgHandler.php里通过$_FILES['imgs']获取上传的文件了,示例代码:
<?php if(isset($_FILES['imgs'])){ // 遍历上传的文件 foreach($_FILES['imgs']['tmp_name'] as $key => $tmpName){ $fileName = $_FILES['imgs']['name'][$key]; $fileType = $_FILES['imgs']['type'][$key]; $fileSize = $_FILES['imgs']['size'][$key]; $fileError = $_FILES['imgs']['error'][$key]; // 处理文件,比如移动到指定目录 if($fileError === UPLOAD_ERR_OK){ // 确保uploads目录存在且有写入权限 move_uploaded_file($tmpName, './uploads/' . $fileName); echo "文件 $fileName 上传成功"; } } } else { echo "没有接收到上传的文件"; } ?>
额外注意事项
- 确保PHP的
upload_max_filesize和post_max_size配置足够大(在php.ini里设置),避免大文件上传失败。 - 如果前端和后端域名不同,要确保后端设置了正确的CORS响应头,允许文件上传请求。
- 检查文件上传的目标目录是否有写入权限。
内容的提问来源于stack exchange,提问作者Sami Al-Subhi
相关产品推荐
相关产品推荐

