用于编写用于使用 node.js 上传图像的筛选器列表的设计模式
Design pattern for writing a list of filters for image uploading using node.js
我在node中编写一个简单的图像上传器.js并表达4。 发布文件时,随附的图像将通过一系列过滤器运行:
- 这是可接受的 MIME 类型吗?(JPG, GIF, PNG, TIFF)
- 这是否有相应的可接受的扩展?
- 此图像是否小于 2 MB?
- 文件在上传过程中是否已被截断?
我习惯于在同步语言中做这种事情,我会通过一系列 if 运行对象,如果捕获某些内容,则返回 false。 然而,在javascript中,相同的方法将导致发送多个标头。
我已经通过在 else 子句中嵌套过滤器来解决这个问题,但这很快就会变得非常笨拙。 这似乎是一种常见的设计模式,那么处理这样的事情的最佳方法是什么?
应用.js:
var express = require('express')
, fs = require('fs')
, bodyParser = require('body-parser')
, serveStatic = require('serve-static')
, multer = require('multer')
, port = 80
;
var app = express();
app.set('views', __dirname + '/views');
app.set('view engine', 'jade');
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
app.use(multer({ dest: "./images/tmp" }))
app.use(serveStatic(__dirname + '/public'));
app.listen(port);
app.get('/', function(req, res, next) {
console.log(req);
res.render("uploader");
});
var uploadConfig = {
acceptedMimeTypes : [ "image/jpeg", "image/png", "image/gif", "image/tiff" ],
acceptedExtensions : [ "jpg", "jpeg", "png", "gif", "tiff" ],
maxFileSize : 2000000
};
app.post('/upload', function(req, res, next) {
var image = req.files.image;
var removeTempImage = function() {
fs.unlink('images/tmp/' + image.name)
};
// Here is where things become a mess
if (uploadConfig.acceptedMimeTypes.indexOf(image.mimetype) == -1) {
removeTempImage();
res.send({success: false, message: "Incorrect MIME type"});
} else {
if (uploadConfig.acceptedExtensions.indexOf(image.extension) == -1) {
removeTempImage();
res.send({success: false, message: "Incorrect file extension"});
} else {
if (image.size > uploadConfig.maxFileSize) {
removeTempImage();
res.send({success: false, message: "File is too large"});
} else {
if (image.truncated) {
removeTempImage();
res.send({success: false, message: "The file was truncated"});
} else {
// it survived the gauntlet
fs.rename('images/tmp/' + image.name, 'public/completeImgs/' + image.name, function (err) {
if (err) {
removeTempImage;
res.send({success: false, message: err});
} else {
res.send({success: true, message: "Your image has been saved"});
}
})
}
}
}
}
});
console.log("uploader is listening on port " + port);
上传者.翡翠
doctype
html
head
body
h1 Image Uploader
form(method="post" action="/upload" enctype="multipart/form-data")
input(type="file" name="image")
input(type="submit")
h1 !{test}
好吧,你所有的检查都是同步的。就这样吧:
app.post('/upload', function (req, res, next)
{
var image = req.files.image;
var removeTempImage = function ()
{
fs.unlink('images/tmp/' + image.name)
};
// Here is where things become a mess
if (uploadConfig.acceptedMimeTypes.indexOf(image.mimetype) == -1)
{
removeTempImage();
res.send({ success: false, message: "Incorrect MIME type" });
return;
}
if (uploadConfig.acceptedExtensions.indexOf(image.extension) == -1)
{
removeTempImage();
res.send({ success: false, message: "Incorrect file extension" });
return;
}
if (image.size > uploadConfig.maxFileSize)
{
removeTempImage();
res.send({ success: false, message: "File is too large" });
return;
}
if (image.truncated)
{
removeTempImage();
res.send({ success: false, message: "The file was truncated" });
return;
}
// it survived the gauntlet
fs.rename('images/tmp/' + image.name, 'public/completeImgs/' + image.name, function (err)
{
if (err)
{
removeTempImage;
res.send({ success: false, message: err });
} else
{
res.send({ success: true, message: "Your image has been saved" });
}
});
});
此外,大多数节点 OOTB 异步功能也可作为同步版本使用。
你可以使用像BlueBird这样的Promise库:
Promise.resolve(image)
.then(function(image) {
if (uploadConfig.acceptedMimeTypes.indexOf(image.mimetype) == -1) {
throw "Incorrect MIME type";
}
return image;
})
.then(function(image) {
if (image.size > uploadConfig.maxFileSize) {
throw "File is too large";
}
return image;
})
.then(function(image) {
if (image.truncated) {
throw "The file was truncated";
}
return image;
})
.then(function(image) {
return fs.renameAsync('images/tmp/' + image.name, 'public/completeImgs/' + image.name)
})
.then(function(err) {
if (err)
throw err;
})
.then(function() {
res.send({success: true, message: "Your image has been saved"});
})
.catch(function(err) {
removeTempImage();
res.send({success: false, message: err});
});
我自己还没有使用过 multer,但如果您查看 multer 页面,它有许多选项,其中一个选项至少可以让您消除大小检查。 https://www.npmjs.com/package/multer。 此外,您不必在此处执行任何异步操作。 当你的post函数被调用时,multer对象已经填写完毕,文件正在等你。
但是像这样的事情呢:
var error_messages = '';
if (uploadConfig.acceptedMimeTypes.indexOf(image.mimetype) == -1) {
error_messages = "Incorrect MIME type ";
}
if (uploadConfig.acceptedExtensions.indexOf(image.extension) == -1) {
error_messages += "Incorrect file extension ";
}
if (image.size > uploadConfig.maxFileSize) {
error_messages += "File is too large ");
}
if (image.truncated) {
error_messages += "The file was truncated ";
}
if(error_messages === ''){
fs.rename('images/tmp/' + image.name, 'public/completeImgs/' + image.name, function (err) {
if (err) {
removeTempImage;
res.send({success: false, message: err});
}
else {
res.send({success: true, message: "Your image has been saved"});
}
});
}
else {
res.send({success: false, message: error_messages});
}
诚然,像这样连接错误消息是很糟糕的。 你可以把它们放在一个数组中,然后将数组传递给视图或其他东西。
相关文章:
- AngularJS单选筛选不适用于Name、Description和Field4复选框值
- Regex,用于从字符串中筛选关键字
- 用于筛选无模式集合的最快数据结构
- 用于筛选数据的函数--if.else语句
- 用于根据上一个值筛选序列的惯用clojure和Javascript表达式
- 用于服务器端处理的数据表,包括分页、筛选和搜索
- 用于视觉效果而非声音的 Web 音频筛选器
- 数据表中的 2 个页脚行,1 个用于筛选器,1 个用于求和行
- 用于编写用于使用 node.js 上传图像的筛选器列表的设计模式
- 用于筛选角度的滑动条值
- 用于筛选日期范围之间的数据的沙发基视图
- 主干筛选器集合,用于按名称返回模型
- AngularJs:错误:用于配对项目的自定义筛选器引发错误:“达到 10 次 $digest() 迭代.流产!
- 键控包含用于阻止结果的筛选
- DataTable-分页和筛选器don'不适用于JavaScript生成的表
- 用于搜索JSON数据的自定义筛选器
- Javascript或Jquery筛选出所选对象,用于具有相同数据的其他选择
- AngularJS筛选器不适用于$scope变量
- 用于两个不同路由的公用筛选器
- 创建用于筛选数据表的自定义WHERE子句