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

11次阅读

如何通过 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),现在可安全访问多文件数组:

立即学习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 文件上传陷阱。

text=ZqhQzanResources