关于利用socket.io实现Nodejs上传进度条的问题

关于利用socket.io实现Nodejs上传进度条的问题

我的处理是这样的,不知道对不对。
当ajax提交上传文件时,js中有两步操作
1,socket.emit(‘message’)
2,上传文件
步骤1的目的是告诉后台文件已经开始上传,并实时监测上传文件的百分比并emit
步骤2就是将上传的文件提交给后台的upload,执行上传
现在我的问题是步骤1引起的后台操作 <pre> socket.on(‘message’,function(){ … }) </pre> 在这里,这个操作如何获取上传文件文件名,请大神指教


3 回复

关于利用socket.io实现Nodejs上传进度条的问题

在实现文件上传进度条的过程中,使用Socket.IO可以实现实时通信,让前端能够及时接收到上传进度。下面是详细的实现方法。

前端代码 (JavaScript)

首先,前端需要通过AJAX发起文件上传请求,并且在文件开始上传前向服务器发送一个消息,以通知服务器文件即将开始上传。

// 引入socket.io客户端库
const socket = io();

document.getElementById('uploadForm').addEventListener('submit', function(event) {
    event.preventDefault(); // 阻止表单默认提交行为

    const fileInput = document.getElementById('fileInput');
    const file = fileInput.files[0];

    // 发送消息给服务器,表示文件即将开始上传
    socket.emit('fileStart', { filename: file.name });

    // 创建FormData对象来存储文件数据
    const formData = new FormData();
    formData.append('file', file);

    // 发起文件上传请求
    fetch('/upload', {
        method: 'POST',
        body: formData
    }).then(response => response.json())
      .then(data => console.log(data))
      .catch(error => console.error(error));
});

后端代码 (Node.js + Express + Socket.IO)

在后端,我们需要监听fileStart事件来接收前端发来的文件名信息,并设置相应的处理逻辑来更新文件上传进度。

const express = require('express');
const app = express();
const http = require('http').createServer(app);
const io = require('socket.io')(http);
const multer = require('multer');

app.use(express.static('public'));

// 设置Multer用于处理文件上传
const upload = multer({ dest: 'uploads/' });

io.on('connection', (socket) => {
    console.log('a user connected');

    socket.on('fileStart', (data) => {
        console.log(`File start to upload: ${data.filename}`);
    });
});

app.post('/upload', upload.single('file'), (req, res) => {
    // 这里可以添加更多处理逻辑,例如记录文件上传路径等
    res.json({ message: 'File uploaded successfully' });
});

http.listen(3000, () => {
    console.log('listening on *:3000');
});

解释

  1. 前端

    • 使用socket.emit发送一个名为fileStart的消息到服务器,携带文件名。
    • 使用fetch API发送文件数据到服务器进行上传。
  2. 后端

    • 使用Socket.IO监听fileStart事件,获取文件名信息。
    • 使用Multer中间件处理文件上传。

通过这种方式,你可以在文件上传过程中实时更新前端的进度条。如果需要更精细的上传进度监控,可以在文件上传过程中实时计算已上传的百分比,并通过Socket.IO发送到前端进行显示。


可是express框架上传文件时那个文件名是32个字符组成的,跟上传前的原名不一样,像07033dbe5690d02a3dcdbd3cc77a53f7之类的

为了实现文件上传进度条,可以使用Socket.IO在客户端和服务器之间实现实时通信,以便更新文件上传进度。以下是一个简单的示例来展示如何实现这一点。

客户端代码 (HTML + JavaScript)

首先,在前端页面中创建一个表单用于选择文件:

<form id="uploadForm">
    <input type="file" name="uploadFile" id="uploadFile" />
    <button type="submit">上传文件</button>
</form>

<div id="progress"></div>

然后,使用JavaScript来处理文件上传和进度更新:

document.getElementById('uploadForm').addEventListener('submit', function(event) {
    event.preventDefault();
    
    const fileInput = document.getElementById('uploadFile');
    const file = fileInput.files[0];
    
    const socket = io(); // 假设已经连接到Socket.IO服务
    
    // Step 1: 通知服务器文件开始上传
    socket.emit('startUpload', { fileName: file.name });

    // 创建FormData对象
    const formData = new FormData();
    formData.append('uploadFile', file);

    // 发起AJAX请求进行文件上传
    fetch('/upload', {
        method: 'POST',
        body: formData
    }).then(response => response.json())
      .then(data => console.log(data))
      .catch(error => console.error(error));
});

服务器端代码 (Node.js + Express)

接下来,在服务器端设置一个监听器来接收Socket.IO事件,并处理文件上传请求:

const express = require('express');
const http = require('http');
const socketIo = require('socket.io');
const fs = require('fs');
const path = require('path');

const app = express();
const server = http.createServer(app);
const io = socketIo(server);

// 监听客户端发起的上传请求
io.on('connection', socket => {
    socket.on('startUpload', ({ fileName }) => {
        console.log(`文件开始上传: ${fileName}`);
        // 更新进度信息
        socket.emit('progress', { percent: 0 });
    });
});

app.post('/upload', (req, res) => {
    let uploadStream = req.file.createReadStream();
    let totalSize = req.file.size;
    let uploadedSize = 0;

    uploadStream.on('data', chunk => {
        uploadedSize += chunk.length;
        const percent = Math.floor((uploadedSize / totalSize) * 100);
        io.emit('progress', { percent });
    });

    uploadStream.pipe(fs.createWriteStream(path.join(__dirname, '/uploads/', req.file.originalname)));
    res.send({ message: '文件已成功上传' });
});

server.listen(3000, () => {
    console.log('Server is running on port 3000');
});

在这个例子中,我们首先通过Socket.IO从客户端接收文件开始上传的通知,然后开始上传文件。服务器端会计算当前上传的百分比,并通过Socket.IO发送回客户端以更新进度条。

回到顶部