如何通过AJAX将JSON数组中的图片传递给PHP并保存?
问题原因
move_uploaded_file 仅支持处理通过 multipart/form-data 格式上传的文件(也就是传统表单或FormData提交的文件)。当你用JSON.stringify序列化包含File对象的数组时,File对象会被转成普通的序列化结构,丢失了文件的临时存储信息和二进制数据——PHP从php://input拿到的只是文件的描述字段(比如文件名),没有实际可操作的文件资源,自然没法用move_uploaded_file保存。
解决方案
方案一:改用FormData上传(推荐,高效且兼容原有逻辑)
放弃JSON序列化,直接用FormData包装文本和文件数据,这样PHP可以通过$_POST和$_FILES正常获取数据,沿用你原来的文件保存逻辑即可。
前端代码
// 构建FormData const formData = new FormData(); formData.append('title', '你的标题内容'); formData.append('content', '你的正文内容'); // 追加文件(假设文件选择器id为fileInput) formData.append('img', document.getElementById('fileInput').files[0]); // 发送AJAX请求 fetch('你的后端接口.php', { method: 'POST', body: formData }) .then(res => res.json()) .then(result => console.log(result)) .catch(err => console.error(err));
后端PHP代码
// 获取文本字段 $title = $_POST["title"]; $content = $_POST["content"]; // 获取文件信息 $imgTmpPath = $_FILES["img"]["tmp_name"]; $imgName = $_FILES["img"]["name"]; // 可自定义文件名,比如加时间戳避免重复 // 确保uploads目录存在且有写入权限 if (!is_dir('uploads')) { mkdir('uploads', 0755, true); } // 保存文件 if (move_uploaded_file($imgTmpPath, "uploads/" . $imgName)) { echo json_encode(['status' => 'success', 'msg' => '文件保存成功']); } else { echo json_encode(['status' => 'error', 'msg' => '文件保存失败']); }
方案二:强制用JSON传输(转Base64编码)
如果业务必须用JSON格式,需要在前端将图片转成Base64编码,后端解码后用file_put_contents写入文件(不再用move_uploaded_file)。
前端代码
// 将文件转为Base64的工具函数 function fileToBase64(file) { return new Promise((resolve, reject) => { const reader = new FileReader(); reader.onload = () => resolve(reader.result); reader.onerror = err => reject(err); reader.readAsDataURL(file); }); } // 准备并发送数据 const fileInput = document.getElementById('fileInput'); if (fileInput.files.length > 0) { fileToBase64(fileInput.files[0]).then(base64Str => { const data = { title: '你的标题', content: '你的内容', img: base64Str, img_name: fileInput.files[0].name }; fetch('你的后端接口.php', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(data) }) .then(res => res.json()) .then(result => console.log(result)) .catch(err => console.error(err)); }); }
后端PHP代码
$unstringified = json_decode(file_get_contents("php://input"), true); $title = $unstringified["title"]; $content = $unstringified["content"]; $base64Img = $unstringified["img"]; $imgName = $unstringified["img_name"]; // 解码Base64(去掉前缀"data:image/xxx;base64,") $imgContent = base64_decode(preg_replace('#^data:image/\w+;base64,#i', '', $base64Img)); // 确保uploads目录存在 if (!is_dir('uploads')) { mkdir('uploads', 0755, true); } // 写入文件 $savePath = "uploads/" . $imgName; if (file_put_contents($savePath, $imgContent)) { echo json_encode(['status' => 'success', 'msg' => '文件保存成功']); } else { echo json_encode(['status' => 'error', 'msg' => '文件保存失败']); }
注意事项
- 优先选择FormData方案:Base64编码会让文件体积增加约30%,传输效率更低;FormData是标准的文件上传方式,兼容性更好。
- 确保
uploads目录存在且拥有写入权限(Linux下可设置chmod 755 uploads)。
内容的提问来源于stack exchange,提问作者trying2code
相关产品推荐
相关产品推荐

