jQuery 上传多个文件及进度条实现指南

在现代 web 开发中,文件上传是一个非常常见的需求。使用 jQuery 进行文件上传并显示进度条,可以给用户提供更好的使用体验。本文将为你详细介绍如何实现 jQuery 上传多个文件及进度条的功能,包括步骤、所需代码和详细解释。

工作流程

我们可以将实现过程分为几个步骤,如下表所示:

步骤 描述
1 创建 HTML 界面
2 编写 jQuery 上传文件的脚本
3 使用 Ajax 发送文件
4 显示上传进度条
5 处理服务器端的文件上传请求

步骤详解

步骤 1:创建 HTML 界面

首先,我们需要一个简单的 HTML 界面,让用户可以选择多个文件并展示上传进度。

<!DOCTYPE html>
<html lang="zh">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>文件上传示例</title>
    <script src="
    <link rel="stylesheet" href="styles.css">
</head>
<body>
    上传多个文件
    <input type="file" id="fileUpload" multiple>
    <button id="uploadBtn">上传</button>
    <div id="progressContainer"></div>
    <script src="script.js"></script>
</body>
</html>
  • input type="file":允许用户选择一个或多个文件(使用 multiple 属性)。
  • button:点击按钮时开始上传文件。
  • div:用于展示上传进度。

步骤 2:编写 jQuery 上传文件的脚本

接下来,我们会使用 jQuery 编写上传文件的脚本,监听上传按钮的点击事件。

// script.js
$(document).ready(function() {
    $('#uploadBtn').click(function() {
        var files = $('#fileUpload')[0].files; // 获取选中的文件
        if (files.length === 0) {
            alert("请先选择文件!");
            return;
        }
        uploadFiles(files);
    });
});
  • $(document).ready(function() {...}):确保 DOM 加载完成后再执行代码。
  • $('#uploadBtn').click(function() {...}):为上传按钮绑定点击事件。
  • $('#fileUpload')[0].files:获取用户选择的文件。

步骤 3:使用 Ajax 发送文件

我们将使用 FormData$.ajax 方法将文件发送到服务器。

function uploadFiles(files) {
    $.each(files, function(index, file) {
        var formData = new FormData();
        formData.append('file', file); // 将文件添加到 FormData 对象

        $.ajax({
            url: 'upload.php', // 服务器处理文件上传的 URL
            type: 'POST',
            data: formData,
            processData: false, // 不处理数据
            contentType: false, // 不设置内容类型
            xhr: function() {
                var xhr = new window.XMLHttpRequest();
                xhr.upload.addEventListener('progress', function(evt) {
                    if (evt.lengthComputable) {
                        var percentComplete = evt.loaded / evt.total * 100; // 计算上传进度百分比
                        updateProgress(index, percentComplete); // 调用更新进度函数
                    }
                }, false);
                return xhr;
            },
            success: function(response) {
                console.log('文件上传成功:', response);
            },
            error: function() {
                console.error('文件上传失败!');
            }
        });
    });
}
  • new FormData():创建一个新的 FormData 对象用于文件上传。
  • xhr.upload.addEventListener('progress', function(evt) {...}):监听上传进度事件,计算并更新上传进度。

步骤 4:显示上传进度条

我们需要一个函数来更新进度条并添加到页面中。

function updateProgress(index, percentComplete) {
    var progressBar = $('#progressContainer').find('.progress-bar[data-index="' + index + '"]');
    if (progressBar.length === 0) {
        progressBar = $('<div class="progress-bar" data-index="' + index + '"></div>');
        $('#progressContainer').append(progressBar); // 添加进度条到容器
    }
    progressBar.css('width', percentComplete + '%'); // 更新进度条的宽度
    progressBar.text(Math.round(percentComplete) + '%'); // 更新进度文本
}
  • $('#progressContainer').find('.progress-bar[data-index="' + index + '"]'):查找对应文件的进度条。
  • progressBar.css('width', percentComplete + '%'):以百分比形式更新进度条宽度。

步骤 5:处理服务器端的文件上传请求

在与前端交互的同时,需要在服务器端编写处理文件上传的代码。以下是一个简单的 PHP 示例(upload.php):

<?php
if ($_SERVER['REQUEST_METHOD'] == 'POST' && isset($_FILES['file'])) {
    $file = $_FILES['file'];
    $uploadDirectory = 'uploads/';
    
    if (move_uploaded_file($file['tmp_name'], $uploadDirectory . basename($file['name']))) {
        echo json_encode(['status' => 'success', 'file' => $file['name']]);
    } else {
        echo json_encode(['status' => 'error', 'message' => '文件上传失败!']);
    }
} else {
    echo json_encode(['status' => 'error', 'message' => '无效的请求!']);
}
?>
  • $_FILES['file']:获取上传的文件信息。
  • move_uploaded_file():将上传的文件移动到目标目录。

完整示例代码

将上述代码整合在一起,就可以实现一个简单的多文件上传及进度条效果。

<!-- Index.html -->
<!DOCTYPE html>
<html lang="zh">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>文件上传示例</title>
    <script src="
    <style>
        .progress-bar {
            background-color: #4caf50;
            height: 30px;
            margin: 5px 0;
            width: 0;
            color: white;
            text-align: center;
        }
    </style>
</head>
<body>
    上传多个文件
    <input type="file" id="fileUpload" multiple>
    <button id="uploadBtn">上传</button>
    <div id="progressContainer"></div>
    <script src="script.js"></script>
</body>
</html>
// script.js
$(document).ready(function() {
    $('#uploadBtn').click(function() {
        var files = $('#fileUpload')[0].files;
        if (files.length === 0) {
            alert("请先选择文件!");
            return;
        }
        uploadFiles(files);
    });
});

function uploadFiles(files) {
    $.each(files, function(index, file) {
        var formData = new FormData();
        formData.append('file', file);

        $.ajax({
            url: 'upload.php',
            type: 'POST',
            data: formData,
            processData: false,
            contentType: false,
            xhr: function() {
                var xhr = new window.XMLHttpRequest();
                xhr.upload.addEventListener('progress', function(evt) {
                    if (evt.lengthComputable) {
                        var percentComplete = evt.loaded / evt.total * 100;
                        updateProgress(index, percentComplete);
                    }
                }, false);
                return xhr;
            },
            success: function(response) {
                console.log('文件上传成功:', response);
            },
            error: function() {
                console.error('文件上传失败!');
            }
        });
    });
}

function updateProgress(index, percentComplete) {
    var progressBar = $('#progressContainer').find('.progress-bar[data-index="' + index + '"]');
    if (progressBar.length === 0) {
        progressBar = $('<div class="progress-bar" data-index="' + index + '"></div>');
        $('#progressContainer').append(progressBar);
    }
    progressBar.css('width', percentComplete + '%');
    progressBar.text(Math.round(percentComplete) + '%');
}
// upload.php
<?php
if ($_SERVER['REQUEST_METHOD'] == 'POST' && isset($_FILES['file'])) {
    $file = $_FILES['file'];
    $uploadDirectory = 'uploads/';
    
    if (move_uploaded_file($file['tmp_name'], $uploadDirectory . basename($file['name']))) {
        echo json_encode(['status' => 'success', 'file' => $file['name']]);
    } else {
        echo json_encode(['status' => 'error', 'message' => '文件上传失败!']);
    }
} else {
    echo json_encode(['status' => 'error', 'message' => '无效的请求!']);
}
?>

结论

通过上述步骤,你可以轻松实现一个支持多个文件上传的功能,同时也能让用户在上传过程中看到上传进度条。这种用户交互的方式能够提升用户体验。希望这篇文章能帮助到你,让你在文件上传的开发过程中更得心应手。

如果你还有其他问题或需要进一步的帮助,请随时询问!