node.js 中的多个文件上传和重命名
Multiple File Upload and rename by multer in node.js
我打算使用 multer 上传多个文件,然后将它们重命名回原来的名称。下面是示例代码:
var express = require('express');
var app = express();
var fs = require("fs");
var multer = require('multer');
app.use(express.static('public'));
var upload = multer({ dest: './upload/' });
app.get('/index.html', function (req, res) {
res.sendFile(__dirname + "/" + "index.html");
})
app.post('/file_upload', upload.array('theFile', 2), function (req, res, next) {
var errorcode = 0;
for (var i = 0; i < req.files.length; i++) {
fs.rename(req.files[i].path, req.files[i].destination + req.files[i].originalname, function (err) {
errorcode = err;
}(i));
}
if (errorcode != 0) {
console.log("errorcode is " + errorcode);
res.sendStatus(500);
return;
} else {
res.json({
message: 'File uploaded successfully',
});
}
})
var server = app.listen(8089, function () {
var host = server.address().address
var port = server.address().port
console.log("Example app listening at http://%s:%s", host, port)
})
我正在 windows 服务器上测试上述代码。我的观察是文件可以成功上传,但 fs.rename() 不断返回错误“1”。并且目标文件夹中重命名的文件始终为 1Kb。重命名功能似乎打算获取可能仍在上传的文件。我不确定我的理解是否正确。如果有,有没有办法判断文件是否上传完整?对我的问题有什么建议吗?
为什么不使用 Multer 的内置重命名功能?
改编自文档:
var storage = multer.diskStorage({
destination: '/path/to/uploads/folder',
filename: function (req, file, cb) {
// Here we specify the file name to save it as
cb(null, file.originalname);
}
})
// And we can use it for example like this:
app.post('/upload', upload.single('image'), function (req, res, next) {
// req.file is the `image` file
// req.body will hold the text fields, if there were any
})
但是,如果您采用这种方法,则应注意以下几点:
- 客户端可以发送任何类型的文件,带有任何(可能不正确的)扩展名。这是一个潜在的安全风险。
- 如果上传两个同名文件,第二个文件将覆盖第一个文件。
- 如果您将这些文件提供给其他用户,安全风险会大大增加。攻击者可以创建脚本或 HTML 页面并将其上传,可能为其提供不同的文件扩展名。它有多种可能 运行,例如如果用户试图在新选项卡中打开它,因为图像没有显示。这一点的全部含义以及如何处理它是他们自己的话题。
- 最后,非常非常确保用户不能写入上传文件夹以外的目录。当
file.originalname
类似于 ../../index.js
时会发生什么?将文件名转换为 slug 可能会更好。
我打算使用 multer 上传多个文件,然后将它们重命名回原来的名称。下面是示例代码:
var express = require('express');
var app = express();
var fs = require("fs");
var multer = require('multer');
app.use(express.static('public'));
var upload = multer({ dest: './upload/' });
app.get('/index.html', function (req, res) {
res.sendFile(__dirname + "/" + "index.html");
})
app.post('/file_upload', upload.array('theFile', 2), function (req, res, next) {
var errorcode = 0;
for (var i = 0; i < req.files.length; i++) {
fs.rename(req.files[i].path, req.files[i].destination + req.files[i].originalname, function (err) {
errorcode = err;
}(i));
}
if (errorcode != 0) {
console.log("errorcode is " + errorcode);
res.sendStatus(500);
return;
} else {
res.json({
message: 'File uploaded successfully',
});
}
})
var server = app.listen(8089, function () {
var host = server.address().address
var port = server.address().port
console.log("Example app listening at http://%s:%s", host, port)
})
我正在 windows 服务器上测试上述代码。我的观察是文件可以成功上传,但 fs.rename() 不断返回错误“1”。并且目标文件夹中重命名的文件始终为 1Kb。重命名功能似乎打算获取可能仍在上传的文件。我不确定我的理解是否正确。如果有,有没有办法判断文件是否上传完整?对我的问题有什么建议吗?
为什么不使用 Multer 的内置重命名功能?
改编自文档:
var storage = multer.diskStorage({
destination: '/path/to/uploads/folder',
filename: function (req, file, cb) {
// Here we specify the file name to save it as
cb(null, file.originalname);
}
})
// And we can use it for example like this:
app.post('/upload', upload.single('image'), function (req, res, next) {
// req.file is the `image` file
// req.body will hold the text fields, if there were any
})
但是,如果您采用这种方法,则应注意以下几点:
- 客户端可以发送任何类型的文件,带有任何(可能不正确的)扩展名。这是一个潜在的安全风险。
- 如果上传两个同名文件,第二个文件将覆盖第一个文件。
- 如果您将这些文件提供给其他用户,安全风险会大大增加。攻击者可以创建脚本或 HTML 页面并将其上传,可能为其提供不同的文件扩展名。它有多种可能 运行,例如如果用户试图在新选项卡中打开它,因为图像没有显示。这一点的全部含义以及如何处理它是他们自己的话题。
- 最后,非常非常确保用户不能写入上传文件夹以外的目录。当
file.originalname
类似于../../index.js
时会发生什么?将文件名转换为 slug 可能会更好。