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

单文件逐个上传覆盖问题求助 附完整上传代码

单文件逐个上传时覆盖问题的解决方案

问题现象

多文件一次性上传可正常完成,但逐个选择单文件上传时,最后上传的文件会覆盖之前所有已选文件。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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 17:01:08