如何通过 AJAX 正确上传多文件并在 PHP 中安全处理

如何通过 AJAX 正确上传多文件并在 PHP 中安全处理

本文详解 ajax 多文件上传时常见的 `$_files` 为空、`[object filelist]` 字符串化等错误原因,提供完整的前端 formdata 构建方案与后端 php 文件解析逻辑,确保多文件上传稳定可靠。

在使用 AJAX 上传 的文件时,一个常见却极易被忽视的错误是:直接将整个 FileList 对象(如 input.files)作为单个值 append 到 FormData 中,例如:

formData.append('listFiles', inputFiles); // ❌ 错误!FileList 被转为 "[object FileList]" 字符串

这会导致 PHP 接收到的不是预期的文件上传数据,而是字符串 “[object FileList]”,因此 $_FILES[‘listFiles’] 为 null,进而触发 Undefined array key “listFiles” 等警告——正如你看到的 var_dump($_POST) 输出所示。

✅ 正确做法是:遍历 FileList,对每个 File 对象单独调用 formData.append(),并使用带 [] 的键名(如 ‘fileList[]’),使 PHP 自动将其识别为数组格式的上传项:

function updateList(nrDoc) {
    const inputFiles = $('#adaugaFisiere')[0].files; // ✅ 获取原生 DOM 元素的 files 属性
    const formData = new FormData();

    // ✅ 正确:逐个添加文件,key 名含 [] 表示多文件数组
    for (let i = 0; i < inputFiles.length; i++) {
        formData.append('fileList[]', inputFiles[i]);
    }

    // ✅ 可选:附加其他表单字段(如 ID、操作标识等)
    formData.append('nextId', nrDoc);
    formData.append('action', 'upload');

    $.ajax({
        url: 'exec/files-upload.php',
        type: 'POST',
        data: formData,
        cache: false,
        contentType: false, // ❗ 必须设为 false,让浏览器自动设置 multipart/form-data 及 boundary
        processData: false, // ❗ 必须设为 false,避免 jQuery 将 FormData 序列化为字符串
        success: function(html) {
            $('#fileList').html(html);
        },
        error: function(xhr, status, error) {
            console.error('Upload failed:', error);
            alert('Eroare la încărcare');
        }
    });
}

? 注意:$('#adaugaFisiere').prop('files') 在 jQuery 中可能返回非标准对象,建议使用 $('#adaugaFisiere')[0].files 或 document.getElementById('adaugaFisiere').files 获取原生 FileList。

在 PHP 后端(exec/files-upload.php),现在可安全访问多文件数组:

Rationale

Rationale

Rationale 是一款可帮助企业主、经理和个人做出艰难的决定的AI工具

下载

立即学习PHP免费学习笔记(深入)”;

 10 * 1024 * 1024) { // 10MB 限制
            continue;
        }

        // ✅ 安全保存(建议使用 uniqid() + 验证 MIME 类型)
        $safeName = uniqid('upload_') . '.' . $ext;
        $uploadPath = __DIR__ . '/../uploads/' . $safeName;

        if (move_uploaded_file($tmpPath, $uploadPath)) {
            echo "
✓ Încărcat: {$originalName}
"; } } else { echo "
✗ Eroare la încărcarea lui {$names[$i]}: cod {$errors[$i]}
"; } }

? 关键要点总结

  • FormData.append(key, value) 中的 value 必须是单个 File 对象,而非 FileList;
  • 使用 key[](如 'fileList[]')才能让 PHP 解析为 $_FILES['fileList']['name'][0] 等多维结构;
  • contentType: false 和 processData: false 是发送二进制文件的硬性要求;
  • 始终校验 $_FILES[...]['error'] 值,不可仅依赖 name 是否存在;
  • 生产环境务必增加 MIME 类型验证、文件头检测、路径白名单等安全措施。

遵循以上规范,即可彻底解决 "[object FileList]" 字符串化及 Undefined array key 等典型 AJAX 文件上传陷阱。

https://www.php.cn/faq/1973696.html

发表回复

Your email address will not be published. Required fields are marked *