性能优化策略
- 减少内存占用
- 流式处理:在文件上传时,使用流(stream)而不是一次性读取整个文件到内存。Node.js 提供了
fs.createReadStream
和 fs.createWriteStream
来实现流式读写。
- 示例代码:
const express = require('express');
const app = express();
const multer = require('multer');
const storage = multer.memoryStorage();
const upload = multer({ storage: storage });
app.post('/upload', upload.single('file'), (req, res) => {
const readStream = require('fs').createReadStream(req.file.path);
const writeStream = require('fs').createWriteStream('uploads/' + req.file.originalname);
readStream.pipe(writeStream);
readStream.on('error', (err) => {
console.error(err);
res.status(500).send('Error uploading file');
});
writeStream.on('finish', () => {
res.send('File uploaded successfully');
});
});
const port = 3000;
app.listen(port, () => {
console.log(`Server running on port ${port}`);
});
- 解释:这里使用
multer
中间件接收文件,然后通过 createReadStream
和 createWriteStream
以流的方式将文件从临时位置移动到目标位置,避免了将整个文件加载到内存中。
- 提升I/O效率
- 使用缓存:对于频繁下载的文件,可以考虑使用缓存。例如,使用
node - cache - manager
库。
- 示例代码:
const express = require('express');
const app = express();
const CacheManager = require('cache - manager');
const cache = CacheManager.caching({
store: 'memory',
max: 100,
ttl: 60 * 1000 // 1 minute
});
app.get('/download/:filename', async (req, res) => {
const cachedFile = await cache.get(req.params.filename);
if (cachedFile) {
res.set('Content - Type', 'application/octet - stream');
res.send(cachedFile);
} else {
const file = require('fs').readFileSync('downloads/' + req.params.filename);
cache.set(req.params.filename, file);
res.set('Content - Type', 'application/octet - stream');
res.send(file);
}
});
const port = 3000;
app.listen(port, () => {
console.log(`Server running on port ${port}`);
});
- 解释:代码中使用
cache - manager
库实现了内存缓存。如果文件在缓存中,则直接从缓存中返回,减少了磁盘 I/O 操作。
安全性加固策略
- 防止文件上传漏洞
- 文件类型验证:使用
file - type
库来验证文件的真实类型,防止文件类型伪造。
- 示例代码:
const express = require('express');
const app = express();
const multer = require('multer');
const fileType = require('file - type');
const storage = multer.memoryStorage();
const upload = multer({ storage: storage });
app.post('/upload', upload.single('file'), async (req, res) => {
const type = await fileType.fromBuffer(req.file.buffer);
if (!type ||!['image/png', 'image/jpeg'].includes(type.mime)) {
return res.status(400).send('Only PNG and JPEG files are allowed');
}
const writeStream = require('fs').createWriteStream('uploads/' + req.file.originalname);
writeStream.write(req.file.buffer);
writeStream.end();
writeStream.on('finish', () => {
res.send('File uploaded successfully');
});
});
const port = 3000;
app.listen(port, () => {
console.log(`Server running on port ${port}`);
});
- 解释:
file - type
库通过分析文件头来确定文件的真实类型,这里只允许 PNG 和 JPEG 文件上传。
- 路径穿越防范:对上传文件的路径进行严格检查和过滤,避免恶意用户通过路径穿越访问系统文件。
- 示例代码:
const express = require('express');
const app = express();
const multer = require('multer');
const storage = multer.memoryStorage();
const upload = multer({ storage: storage });
app.post('/upload', upload.single('file'), (req, res) => {
const sanitizedFileName = req.file.originalname.replace(/[^\w\s.-]/g, '');
if (sanitizedFileName.includes('..')) {
return res.status(400).send('Invalid file name');
}
const writeStream = require('fs').createWriteStream('uploads/' + sanitizedFileName);
writeStream.write(req.file.buffer);
writeStream.end();
writeStream.on('finish', () => {
res.send('File uploaded successfully');
});
});
const port = 3000;
app.listen(port, () => {
console.log(`Server running on port ${port}`);
});
- 解释:代码中通过正则表达式去除文件名中的非法字符,并检查文件名中是否包含
..
来防止路径穿越。
- 防止下载过程中的数据泄露
- 访问控制:确保只有授权用户可以下载文件。例如,结合身份验证中间件(如
express - jwt
用于 JWT 验证)。
- 示例代码:
const express = require('express');
const jwt = require('jsonwebtoken');
const app = express();
const secret = 'your - secret - key';
// 模拟用户登录
app.post('/login', (req, res) => {
const user = { id: 1 };
const token = jwt.sign(user, secret);
res.send({ token });
});
// 下载文件路由,需要 JWT 验证
app.get('/download/:filename', (req, res, next) => {
const token = req.headers['authorization'];
if (!token) {
return res.status(401).send('Access denied. No token provided.');
}
try {
const decoded = jwt.verify(token.replace('Bearer ', ''), secret);
req.user = decoded;
next();
} catch (err) {
return res.status(400).send('Invalid token');
}
}, (req, res) => {
const file = require('fs').readFileSync('downloads/' + req.params.filename);
res.set('Content - Type', 'application/octet - stream');
res.send(file);
});
const port = 3000;
app.listen(port, () => {
console.log(`Server running on port ${port}`);
});
- 解释:这里使用
express - jwt
进行 JWT 验证,只有携带有效 JWT 的用户才能下载文件,防止数据泄露给未授权用户。