在前端开发中,文件上传是一个常见的需求。然而,在上传较大的文件时,用户需要等待较长时间才能完成上传,这会给用户带来不好的体验。为了改善用户体验,我们可以使用进度条来展示上传进度。在本文中,我们将介绍如何使用 Express.js 实现文件上传进度条的方法。
实现思路
使用 Express.js 实现文件上传进度条的方法,主要分为以下几个步骤:
- 创建一个上传路由,用于处理文件上传请求。
- 使用 multer 中间件,处理文件上传,并将上传进度传递给回调函数。
- 在回调函数中,通过 socket.io 将上传进度传递给前端页面。
- 在前端页面中,使用进度条组件展示上传进度。
代码实现
后端代码
首先,我们需要创建一个上传路由,用于处理文件上传请求。在路由中,我们使用 multer 中间件,处理文件上传,并将上传进度传递给回调函数。
const express = require('express'); const multer = require('multer'); const path = require('path'); const router = express.Router(); const storage = multer.diskStorage({ destination: function (req, file, cb) { cb(null, 'uploads/') }, filename: function (req, file, cb) { cb(null, file.fieldname + '-' + Date.now() + path.extname(file.originalname)) } }); const upload = multer({ storage: storage, limits: { fileSize: 1000000 }, fileFilter: function (req, file, cb) { checkFileType(file, cb); } }).single('file'); router.post('/upload', function (req, res) { upload(req, res, function (err) { if (err) { console.log(err); return res.status(500).send(err.message); } res.status(200).send('File uploaded successfully'); }); }); function checkFileType(file, cb) { const filetypes = /jpeg|jpg|png/; const extname = filetypes.test(path.extname(file.originalname).toLowerCase()); const mimetype = filetypes.test(file.mimetype); if (extname && mimetype) { return cb(null, true); } else { cb('Error: Images Only!'); } }
在回调函数中,我们通过 socket.io 将上传进度传递给前端页面。具体实现如下:
const io = require('socket.io')(server); io.on('connection', function (socket) { console.log('Socket connected: ' + socket.id); socket.on('start', function (data) { console.log('Start uploading: ' + data.filename); const stream = ss.createStream(); const filename = path.basename(data.filename); const size = data.size; const type = data.type; const folder = data.folder; const uploadPath = path.join(__dirname, '..', folder, filename); ss(socket).emit('stream', stream, { size: size, type: type, filename: filename }); fs.mkdirSync(path.join(__dirname, '..', folder), { recursive: true }); const writable = fs.createWriteStream(uploadPath); data.stream.pipe(writable); data.stream.on('data', function (chunk) { const progress = (chunk.length / size) * 100; socket.emit('progress', { progress: progress }); }); data.stream.on('end', function () { console.log('Upload completed: ' + filename); socket.emit('end', { filename: filename }); }); }); });
前端代码
在前端页面中,我们使用 socket.io 客户端,连接到服务器,并监听上传进度事件。具体实现如下:
const socket = io(); $('#upload-form').submit(function (e) { e.preventDefault(); const file = $('#file-input')[0].files[0]; const formData = new FormData(); formData.append('file', file); socket.emit('start', { filename: file.name, size: file.size, type: file.type, folder: 'uploads' }); const stream = ss.createStream(); ss(socket).emit('stream', stream, { size: file.size, type: file.type, filename: file.name }); const blobStream = ss.createBlobReadStream(file); const size = 0; const progressBar = $('#progress-bar'); blobStream.on('data', function (chunk) { size += chunk.length; const progress = Math.floor(size / file.size * 100); progressBar.css('width', progress + '%'); progressBar.text(progress + '%'); socket.emit('progress', { progress: progress }); }); blobStream.pipe(stream); socket.on('end', function (data) { console.log('Upload completed: ' + data.filename); progressBar.css('width', '0%'); progressBar.text('0%'); }); });
总结
使用 Express.js 实现文件上传进度条的方法,可以改善用户体验,提高用户满意度。在本文中,我们介绍了实现思路,并给出了具体代码实现。希望本文能够对您有所帮助。
来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/658cef8aeb4cecbf2d2ce909