SSE 实现文件上传实时进度展示的教程

在前端开发中,文件上传功能是一个很常见的需求,但是常规的文件上传方式并不能实现实时的上传进度展示。而使用 SSE 技术可以实现实时展示上传进度,本文将介绍如何使用 SSE 技术实现文件上传实时进度展示。

什么是 SSE?

SSE(Server-Sent Events),即服务端推送技术,是一种浏览器与服务器之间的单向通信方式。利用 SSE,服务器可以向浏览器推送数据,而不需要浏览器发出请求。SSE 可以用于实现服务端向浏览器推送实时通知、实时数据等功能。

实现思路

实现文件上传实时进度展示,需要从两个方面入手:文件上传和上传进度显示。文件上传可以通过 AJAX 实现,而上传进度显示则需要使用 SSE 技术。

具体实现思路如下:

  1. 创建一个 SSE 连接,用于接收上传进度信息;
  2. 通过 AJAX 实现文件上传,并通过回调函数实现实时上传进度的更新;
  3. 上传进度更新时,将进度信息通过 SSE 推送给浏览器;
  4. 浏览器接收到 SSE 推送的上传进度信息后,更新页面中的进度条。

示例代码

HTML 代码:

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>SSE 文件上传实时进度展示</title>
    <script src="//cdn.bootcss.com/jquery/3.1.1/jquery.min.js"></script>
</head>
<body>
    <h1>SSE 文件上传实时进度展示</h1>
    <form id="upload-form">
        <input type="file" id="file-input" name="file">
        <button id="upload-btn">上传文件</button>
    </form>
    <div id="progress-bar"><div></div></div>

    <script src="sse-upload.js"></script>
</body>
</html>

JavaScript 代码(sse-upload.js):

$(document).ready(function() {
    // 创建 SSE 连接
    var eventSource = new EventSource('/progress');

    // 监听上传进度消息
    eventSource.addEventListener('message', function(e) {
        var progress = JSON.parse(e.data).progress;
        updateProgressBar(progress);
    }, false);

    // 更新进度条
    function updateProgressBar(progress) {
        $('#progress-bar > div').css('width', progress + '%');
    }

    // 文件上传
    $('#upload-btn').click(function() {
        var formData = new FormData();
        var inputFile = $('#file-input')[0].files[0];

        formData.append('file', inputFile);

        // AJAX 上传文件
        $.ajax({
            url: '/upload',
            type: 'POST',
            data: formData,
            cache: false,
            contentType: false,
            processData: false,
            xhr: function () {
                var xhr = $.ajaxSettings.xhr();

                if (xhr.upload) {
                    // 监听上传进度
                    xhr.upload.addEventListener('progress', function (e) {
                        if (e.lengthComputable) {
                            var progress = (e.loaded / e.total * 100).toFixed(2);
                            eventSource.send(JSON.stringify({ progress: progress }));
                        }
                    }, false);
                }

                return xhr;
            }
        });
    });
});

服务器代码(Node.js):

var http = require('http');
var fs = require('fs');
var path = require('path');

// 创建 HTTP 服务器
var server = http.createServer(function(req, res) {
    // 处理上传请求
    if (req.method === 'POST' && req.url === '/upload') {
        var file = req.files.file;
        var filePath = path.join(__dirname, 'uploads', file.name);

        // 保存上传的文件
        file.pipe(fs.createWriteStream(filePath));

        // 发送响应
        res.writeHead(200, {'Content-Type': 'text/plain'});
        res.end('File uploaded');
    }
});

// 创建 SSE 连接
var sseClients = [];
var sseServer = http.createServer(function(req, res) {
    // 设置响应头
    // 注意:SSE 响应头中的 Content-Type 和 Connection 必须包含以下内容
    res.writeHead(200, {
        'Content-Type': 'text/event-stream',
        'Cache-Control': 'no-cache',
        'Connection': 'keep-alive'
    });

    // 将响应对象存储到客户端列表中
    sseClients.push(res);

    // 监听连接关闭事件,将连接从客户端列表中移除
    req.on('close', function() {
        sseClients.splice(sseClients.indexOf(res), 1);
    });
});

// 监听 SSE 服务器端口
sseServer.listen(8081, function() {
    console.log('SSE server is running on port 8081');
});

// 监听 HTTP 服务器端口
server.listen(8080, function() {
    console.log('HTTP server is running on port 8080');
});

// 将上传进度推送给所有客户端
function updateSSEClients(progress) {
    var event = 'progress';
    var data = JSON.stringify({ progress: progress });

    for (var i = 0; i < sseClients.length; i++) {
        sseClients[i].write('event: ' + event + '\n' + 'data: ' + data + '\n\n');
    }
}

总结

本文介绍了如何使用 SSE 技术实现文件上传实时进度展示。SSE 技术可以帮助我们实现实时通知、实时数据等功能,极大地扩展了前端应用的功能和应用场景。希望本文能为读者带来帮助,推动 SSE 技术的普及与应用。

来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/65a4a20badd4f0e0ffcf19ae


纠错反馈