您现在的位置是:网站首页 > 文件上传与下载处理文章详情
文件上传与下载处理
陈川
【
Node.js
】
51934人已围观
4335字
文件上传处理
Express框架通过中间件multer
处理文件上传。multer
是一个Node.js中间件,用于处理multipart/form-data
类型的数据,主要用于文件上传。安装multer
后,可以轻松配置上传路径、文件过滤和大小限制。
const express = require('express');
const multer = require('multer');
const path = require('path');
const app = express();
// 配置存储
const storage = multer.diskStorage({
destination: (req, file, cb) => {
cb(null, 'uploads/');
},
filename: (req, file, cb) => {
cb(null, Date.now() + path.extname(file.originalname));
}
});
// 文件过滤
const fileFilter = (req, file, cb) => {
if (file.mimetype === 'image/jpeg' || file.mimetype === 'image/png') {
cb(null, true);
} else {
cb(new Error('Unsupported file type'), false);
}
};
const upload = multer({
storage: storage,
limits: { fileSize: 1024 * 1024 * 5 }, // 5MB限制
fileFilter: fileFilter
});
// 单文件上传路由
app.post('/upload', upload.single('file'), (req, res) => {
res.send('File uploaded successfully');
});
app.listen(3000);
多文件上传使用upload.array()
方法:
app.post('/upload-multiple', upload.array('files', 5), (req, res) => {
// 限制最多5个文件
res.send(`${req.files.length} files uploaded successfully`);
});
文件下载处理
Express提供res.download()
方法实现文件下载功能。该方法会自动设置适当的Content-Type
和Content-Disposition
头部。
app.get('/download', (req, res) => {
const filePath = path.join(__dirname, 'uploads', 'example.pdf');
res.download(filePath, 'custom-filename.pdf', (err) => {
if (err) {
res.status(500).send('File download failed');
}
});
});
对于大文件下载,建议使用流式处理以避免内存问题:
const fs = require('fs');
app.get('/download-large', (req, res) => {
const filePath = path.join(__dirname, 'uploads', 'large-video.mp4');
const stat = fs.statSync(filePath);
res.writeHead(200, {
'Content-Type': 'video/mp4',
'Content-Length': stat.size,
'Content-Disposition': 'attachment; filename=video.mp4'
});
const readStream = fs.createReadStream(filePath);
readStream.pipe(res);
});
文件管理最佳实践
- 安全处理:
- 永远不要信任上传的文件名
- 限制文件类型和大小
- 将上传目录设置为不可执行
// 安全文件名处理
function sanitizeFilename(filename) {
return filename.replace(/[^a-z0-9\.-]/gi, '_').toLowerCase();
}
-
存储优化:
- 考虑使用云存储服务(AWS S3、阿里云OSS等)
- 实现分块上传大文件
- 定期清理临时文件
-
性能考虑:
- 使用CDN分发静态文件
- 实现断点续传功能
- 考虑文件压缩选项
高级文件处理
实现图片即时处理(如缩略图生成):
const sharp = require('sharp');
app.post('/upload-image', upload.single('image'), async (req, res) => {
try {
await sharp(req.file.path)
.resize(300, 300)
.toFile(`uploads/thumbnails/${req.file.filename}`);
res.send('Image processed successfully');
} catch (err) {
res.status(500).send('Image processing failed');
}
});
实现文件分块上传:
// 前端分块上传示例代码
async function uploadFileInChunks(file) {
const chunkSize = 1024 * 1024; // 1MB
const totalChunks = Math.ceil(file.size / chunkSize);
for (let i = 0; i < totalChunks; i++) {
const chunk = file.slice(i * chunkSize, (i + 1) * chunkSize);
const formData = new FormData();
formData.append('chunk', chunk);
formData.append('chunkIndex', i);
formData.append('totalChunks', totalChunks);
formData.append('fileId', file.name + file.size);
await fetch('/upload-chunk', {
method: 'POST',
body: formData
});
}
// 通知服务器合并分块
await fetch('/merge-chunks', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
fileId: file.name + file.size,
fileName: file.name,
totalChunks: totalChunks
})
});
}
错误处理与日志记录
完善的错误处理机制对文件操作至关重要:
// 全局错误处理中间件
app.use((err, req, res, next) => {
if (err.code === 'LIMIT_FILE_SIZE') {
return res.status(413).send('File too large');
}
if (err.message === 'Unsupported file type') {
return res.status(415).send('Invalid file type');
}
console.error('File upload error:', err);
res.status(500).send('File processing error');
});
// 文件操作日志记录
function logFileOperation(action, filePath, userId) {
const timestamp = new Date().toISOString();
const logEntry = `${timestamp} [${action}] ${filePath} by user ${userId}\n`;
fs.appendFile('file_operations.log', logEntry, (err) => {
if (err) console.error('Failed to log file operation', err);
});
}
上一篇: Cookie与Session管理
下一篇: RESTful API开发支持