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

如何通过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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 00:25:32