拥有使用Multer上传图像的Express应用程序。我希望能够做的就是提供这种形象。然而,挑战是当文件被上传时,它不会保存文件扩展名,该文件扩展名是出于安全目的而从我读过的文件中设计的。我需要做的是为相应的mime类型添加正确的扩展名。
技术
文件结构
root
server.js
/uploads
/images
ad58c400e67362118ac1b11f6c4b6c44
...
/routes
drinks.routes.js
uploads.routes.js
通过Postman全程运行。拥有表单元素name
,tagline
,image
。如果我上传" IMG_111.jpg"该图像将通过Multer上传,验证它是一种图像类型,并放置在/images/uploads
中,使用新名称,Multer的默认行为可以创建唯一性。问题是我有filename
但它没有用扩展名保存。
drinks.routes.js
var upload = multer({
dest: 'uploads/images',
fileFilter: function (req, file, callback) {
console.log('running upload file filter');
var fileType = file.mimetype;
if(fileType !== 'image/png' && fileType !== 'image/jpeg' && fileType !== 'image/gif' && fileType !== 'image/jpg') {
return callback(new Error('Only images are allowed'))
}
callback(null, true)
},
}).single('image');
router.route('/').post(passport.authenticate('jwt', { session: false }), upload, function(req, res, next){
var drink = req.body;
var drinkImage = req.file;
console.log('DRINK IMAGE', drinkImage);
Drink.createDrink(drink, drinkImage, function(err, drink, drinkImage){
console.log('creating drink');
if(err){
res.send(err);
}
res.json(drink)
});
});
因此,我可以上传文件,验证文件,使用唯一名称保存文件,不添加扩展名。在我遇到困难的地方,然后检查所请求图像的mime类型,附加扩展并将其发送回响应中。
我最初的想法是创建一个请求图像名称的路径,使用mmmagic来检测mime类型,添加扩展名并提供该文件。但是,所有尝试都失败了。
uploads.routes.js
var express = require('express');
var router = express.Router();
var path = require('path');
var mmm = require('mmmagic');
var Magic = mmm.Magic;
var magic = new Magic(mmm.MAGIC_MIME_TYPE);
router.use(function(req, res, next){
next();
});
router.route('/images/:filename')
.get(function(req,res){
var fileName = req.params.filename;
var constructFile = function(res){
magic.detectFile(__dirname + '/../uploads/images/' + fileName, function(err, result) {
if (err) throw err;
console.log(result);
if (result == 'image/jpeg'){
// return res.sendFile(__dirname + '/../uploads/images/' + fileName + '.jpg');
res.send(express.static(path.join(__dirname, '/../uploads/images'), {index: false, extensions:['jpg']}));
}
});
}
constructFile(res);
})
module.exports = router;
尝试遵循此SO这导致我express.static
。但是,如果我在正确的轨道上并且只是遗漏了一些东西,或者我应该从不同的角度看待这个问题,那么就无法弄清楚。
答案 0 :(得分:0)
您必须先配置您的multer上传器。试试这个:
var multer = require('multer');
//This is for preventing multer from giving name without extention
var storage = multer.diskStorage({
destination: function(req, file, cb) {
cb(null, 'public/files/')
},
filename: function(req, file, cb) {
cb(null, file.originalname);
}
});
但是,如果您仍想拥有唯一的名称,请尝试以下方法:
var storage = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, 'public/files/')
},
filename: function (req, file, cb) {
crypto.pseudoRandomBytes(16, function (err, raw) {
cb(null, raw.toString('hex') + Date.now() + '.' +
mime.extension(file.mimetype));
});
}
});
var upload = multer({ storage: storage });
答案 1 :(得分:0)
这不是最干净的实施,但确实有效。接受Multer #170问题的建议。
<强> uploads.routes.js 强>
router.route('/images/:filename')
.get(function(req,res){
var fileName = req.params.filename;
function getFileType(file, done){
console.log('GETTING FILE TYPE');
magic.detectFile(__dirname + '/../uploads/images/' + fileName, function(err, result) {
if (err) return done(err);
res.setHeader('Content-Type', result)
fs.createReadStream(path.join(__dirname + '/../uploads/images/', req.params.filename)).pipe(res)
});
}
getFileType();
})
缺少的关键部分是:
res.setHeader('Content-Type', result)
fs.createReadStream(path.join(__dirname + '/../uploads/images/', req.params.filename)).pipe(res)
所以现在可以上传文件,验证mime类型,存储为唯一名称,最后调用文件名,检查mime类型,将内容类型设置为mime类型并传递给客户端。