单文件逐个上传覆盖问题求助 附完整上传代码
单文件逐个上传时覆盖问题的解决方案
问题现象
多文件一次性上传可正常完成,但逐个选择单文件上传时,最后上传的文件会覆盖之前所有已选文件。AJAX请求在多文件批量上传时能正确传递所有图片数据,而逐个上传时请求仅包含最后一张图片的信息。
问题根源
- 原生
<input type="file">的files对象仅存储最后一次选择的文件集合,不会自动累加历史选择的文件 - 当前代码未维护全局的文件列表,每次提交时仅将当前输入框内的最后一批文件加入FormData,导致历史文件丢失
解决方案
维护一个全局数组存储所有已选择的文件,每次选择新文件时将其追加到数组中;删除预览图时同步从数组中移除对应文件;提交时遍历全局数组,将所有文件加入FormData后发送请求。
修改后的完整代码
index.php
<!doctype html> <html lang="en"> <head> <!-- Required meta tags --> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <!-- Bootstrap CSS --> <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous"> <title>文件上传示例</title> </head> <style> .pip { float: left; margin-right: 10px; margin-bottom: 10px; } .img-thumb-wrapper { position: relative; } .img-thumb { width: 100px; height: 100px; object-fit: cover; } .remove { position: absolute; top: 5px; right: 5px; cursor: pointer; color: white; background-color: rgba(0,0,0,0.5); padding: 2px 5px; border-radius: 3px; } </style> <body> <form id="myForm" method="post"> <input type="file" id="files" class="file_uploader_file" name="files[]" multiple="true" accept="image/*" /> <p class="validateError" id="imgerror" style="color:red;display:none">请选择图片文件</p> <input type="button" id="fees_stream_submit1" name="submit" value="上传文件"> </form> <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js" type="text/javascript"></script> <script> // 全局存储所有已选择的文件 var selectedFiles = []; (function () { $(document).on('click', '#fees_stream_submit1', function (e) { var form = new FormData(); // 将全局数组中的所有文件加入FormData selectedFiles.forEach(function(file, index) { form.append('file' + index, file); }); $.ajax({ url: "fileuploadmultidata.php", type: "POST", data: form, contentType: false, processData: false, success: function (result) { console.log('上传结果:', result); // 上传成功后可清空文件列表和预览 selectedFiles = []; $('.pip').remove(); } }); }); })(); $(document).ready(function () { if (window.File && window.FileList && window.FileReader) { $("#files").on("change", function (e) { var files = e.target.files; var filesLength = files.length; for (var i = 0; i < filesLength; i++) { var file = files[i]; // 将新文件追加到全局数组 selectedFiles.push(file); var fileReader = new FileReader(); // 使用闭包保存当前文件的引用,避免循环变量问题 (function(currentFile) { fileReader.onload = function (e) { $("<span class='pip'><div class=\"file_uploaded_view img-thumb-wrapper image-preview-height\">" + "<img class=\"img-thumb\" src=\"" + e.target.result + "\" title=\"" + currentFile.name + "\"/>" + "<br/><span class='remove' data-index='" + (selectedFiles.length - 1) + "'><i class='fa fa-trash'></i> 删除</span></span>" + "</div>").insertAfter("#files"); }; fileReader.readAsDataURL(currentFile); })(file); } }); // 处理删除预览图事件 $(document).on('click', '.remove', function () { var index = $(this).data('index'); // 从全局数组中移除对应文件 selectedFiles.splice(index, 1); // 更新剩余预览图的索引 $(this).parents('.pip').remove(); $('.remove').each(function(i) { $(this).data('index', i); }); }); } else { alert("您的浏览器不支持File API,请升级浏览器"); } }); </script> </body> </html>
fileuploadmultidata.php
<?php echo "<pre>"; print_r($_FILES); // 可选:添加文件存储逻辑 $uploadDir = 'uploads/'; if (!is_dir($uploadDir)) { mkdir($uploadDir, 0777, true); } foreach ($_FILES as $file) { if ($file['error'] === UPLOAD_ERR_OK) { $fileName = uniqid() . '_' . basename($file['name']); $targetPath = $uploadDir . $fileName; move_uploaded_file($file['tmp_name'], $targetPath); echo "文件 {$file['name']} 已保存到: {$targetPath}\n"; } } ?>
关键修改点
- 新增全局数组
selectedFiles,用于存储所有已选择的文件 - 文件选择事件中,将新文件追加到全局数组,而非仅依赖输入框的
files对象 - 删除预览图时,同步从全局数组中移除对应文件,并更新剩余预览图的索引
- 提交时遍历全局数组,将所有文件加入FormData,确保所有已选文件都被传递
内容的提问来源于stack exchange,提问作者Pooja m Palande
相关产品推荐
相关产品推荐

