在 Express JS 中使用 Multer 根据扩展名过滤文件
Filter files on the basis of extension using Multer in Express JS
如问题标题所述,我需要根据文件扩展名过滤上传的文件。所以,我浏览了官方文档并搜索了这个网站。
我试过的
我尝试了遇到的解决方案。文件正在上传成功,但问题是如何过滤文件。目前我的 Router.js 文件看起来像这样。
Router.JS
var multer = require('multer');
var storage = multer.diskStorage({ //multers disk storage settings
destination: function (req, file, cb) {
cb(null, './public/uploads/')
},
limits:{
files: 1,
fileSize: 1024 * 1024
},
filename: function (req, file, cb) {
var datetimestamp = Date.now();
cb(null, file.fieldname + '-' + datetimestamp + '.' + file.originalname.split('.')[file.originalname.split('.').length -1])
},
onFileUploadStart: function(file) {
console.log("Inside uploads");
if (file.mimetype == 'image/jpg' || file.mimetype == 'image/jpeg' || file.mimetype == 'image/png') {
return true;
}
else
{
return false;
}
}
});
var upload = multer({ //multer settings
storage: storage
}).single('profilepic');
router.post('/profile', function(req, res){
upload(req,res,function(err){
if(err)
{
console.log(err);
}
else
{
console.log("Image was uploaded");
}
});
});
我尝试回显 onFileUploadStart
中的内容以检查它是否进入该函数。但事实并非如此。除了onFileUploadStart
,我还尝试了fileFilter
,正如link中提到的,但没有帮助。任何建议如何解决这个问题?提前致谢。
如果你习惯web开发,可以在前端验证,不传递给后端,你可以试试:
var file = files[0];
var imageType = /image.*/;
if (!file.type.match(imageType)) {
// do something
}
使用 multer
的示例:
var storage = multer.diskStorage({ //multers disk storage settings
destination: function (req, file, cb) {
cb(null, './public/uploads/')
},
filename: function (req, file, cb) {
var datetimestamp = Date.now();
cb(null, file.fieldname + '-' + datetimestamp + '.' + file.originalname.split('.')[file.originalname.split('.').length -1])
}
});
var upload = multer({ //multer settings
storage: storage,
fileFilter: function (req, file, callback) {
var ext = path.extname(file.originalname);
if(ext !== '.png' && ext !== '.jpg' && ext !== '.gif' && ext !== '.jpeg') {
return callback(new Error('Only images are allowed'))
}
callback(null, true)
},
limits:{
fileSize: 1024 * 1024
}
}).single('profilepic');
摘自Node.js - File upload. The original authors were Iceman and Mikhail. Attribution details can be found on the contributor page. The source is licenced under CC BY-SA 3.0 and may be found in the Documentation archive。参考题目ID:4080 范例ID:14210.
这很有帮助,谢谢。在我的例子中,我需要添加一个中间件以确保 JWToken 就位并使用 构建它XHR。如果其他人需要帮助,这对我有用。在 XHR header.
中传递令牌时可以轻松完成
客户:
const loadHandler = event =>{
// loadHandler mandate
}
const errorHandler = event => {
// error mandate
}
const abortHandler = event => {
// abort mandate
}
const data = new FormData()
data.append('file', upFile)
var formData = new FormData();
var xhr = new window.XMLHttpRequest();
formData.append('files', upFile); // this is a state object set onChange
xhr.open('post', '/uploadFile', true);
xhr.setRequestHeader('token', thetoken); // Passing token in header
xhr.addEventListener("load", loadHandler, false);
xhr.addEventListener("error", errorHandler, false);
xhr.addEventListener("abort", abortHandler, false);
xhr.send(formData);
服务器
const express = require('express'),
app= express.Router(),
rf = require('./RoutFuctions');
...
app.post('/uploadFile', rf.verifyToken, function (req, res, next) {
// upload portion above
});
RoutFunctions.js
const jwt = require('jsonwebtoken')
const tokenTest = (token, res, jwt, caller, next) => {
jwt.verify(token, process.env.SECRET_KEY, err => {
if(err) {
res.sendStatus(403);
console.log('could not verify token');
} else {
console.log("token verified");
next(); // Next middleware
}
});
}
exports.verifyToken = function(req, res, next) {
if(req.body.token !== undefined) { // non upload scenario
var caller = ''
if(req.body.caller !== undefined) caller = req.body.caller;
tokenTest(req.body.token, res, jwt, caller, next)
} else { // attempt to extract token in XHR header upload scenario
if(req.headers.token !== undefined){
var token = req.headers.token
tokenTest(req.headers.token, res, jwt, caller, next)
} else {
res.sendStatus(403);
}
}
}
多个或单个文件的完整实施。
注意:对于单个文件使用 .single('filename') 或 .array('filename',1)
const express = require("express");
const app = express();
var session = require('express-session')
const multer = require("multer");
const path = require("path");
var storage = multer.diskStorage({ //multers disk storage settings
destination: function (req, file, cb) {
cb(null, path.join(__dirname,"uploads"))
},
filename: function (req, file, cb) {
var datetimestamp = Date.now();
cb(null, file.fieldname + '-' + datetimestamp + '.' + file.originalname.split('.')[file.originalname.split('.').length -1])
}
});
var upload = multer({ //multer settings
storage: storage,
fileFilter: function (req, file, callback) {
var ext = path.extname(file.originalname);
if(ext !== '.png' && ext !== '.jpg' && ext !== '.gif' && ext !== '.jpeg') {
return callback(new Error('Only images are allowed'))
}
callback(null, true)
},
limits:{
fileSize: 1024 * 1024
}
}).array('profile',2);
app.post("/upload", upload,(req, res) => {
res.json({
msg:"uploaded"
})
});
app.use((err,req,res,next)=>{
console.log(err.message);
res.status(404).json({
msg:err.message
})
})
app.listen(
8080,
(error) => {
if (error) {
console.log("error");
}
},
() => {
console.log("listening at port 8080");
}
);
注意:您可以通过扩展 Error 并在 err、req、res、next 块中发送自定义消息和状态来创建自己的自定义错误消息
我现在正在测试这个替代方案。对我来说似乎可行,但我仍在评估(
打字稿):
import crypto from 'crypto';
import multer, { FileFilterCallback } from 'multer';
import { resolve } from 'path';
const tmpFolder = resolve(__dirname, '..', '..', 'tmp');
const fileSize = 50 * 1024 * 1024;
export default {
tmpFolder,
fileFilter: (
request: Express.Request,
file: Express.Multer.File,
callback: FileFilterCallback,
) => {
const acceptedTypes = file.mimetype.split('/');
if (acceptedTypes[0] === 'image' || acceptedTypes[0] === 'video') {
callback(null, true);
} else {
callback(null, false);
callback(new Error('Only images and videos formats allowed!'));
}
},
limits: {
fileSize,
},
storage: multer.diskStorage({
destination: tmpFolder,
filename: (request, file, callback) => {
const fileHash = crypto.randomBytes(16).toString('hex');
const fileName = `${fileHash}-${file.originalname}`;
return callback(null, fileName);
},
}),
};
如问题标题所述,我需要根据文件扩展名过滤上传的文件。所以,我浏览了官方文档并搜索了这个网站。
我试过的
我尝试了遇到的解决方案。文件正在上传成功,但问题是如何过滤文件。目前我的 Router.js 文件看起来像这样。
Router.JS
var multer = require('multer');
var storage = multer.diskStorage({ //multers disk storage settings
destination: function (req, file, cb) {
cb(null, './public/uploads/')
},
limits:{
files: 1,
fileSize: 1024 * 1024
},
filename: function (req, file, cb) {
var datetimestamp = Date.now();
cb(null, file.fieldname + '-' + datetimestamp + '.' + file.originalname.split('.')[file.originalname.split('.').length -1])
},
onFileUploadStart: function(file) {
console.log("Inside uploads");
if (file.mimetype == 'image/jpg' || file.mimetype == 'image/jpeg' || file.mimetype == 'image/png') {
return true;
}
else
{
return false;
}
}
});
var upload = multer({ //multer settings
storage: storage
}).single('profilepic');
router.post('/profile', function(req, res){
upload(req,res,function(err){
if(err)
{
console.log(err);
}
else
{
console.log("Image was uploaded");
}
});
});
我尝试回显 onFileUploadStart
中的内容以检查它是否进入该函数。但事实并非如此。除了onFileUploadStart
,我还尝试了fileFilter
,正如link中提到的,但没有帮助。任何建议如何解决这个问题?提前致谢。
如果你习惯web开发,可以在前端验证,不传递给后端,你可以试试:
var file = files[0];
var imageType = /image.*/;
if (!file.type.match(imageType)) {
// do something
}
使用 multer
的示例:
var storage = multer.diskStorage({ //multers disk storage settings
destination: function (req, file, cb) {
cb(null, './public/uploads/')
},
filename: function (req, file, cb) {
var datetimestamp = Date.now();
cb(null, file.fieldname + '-' + datetimestamp + '.' + file.originalname.split('.')[file.originalname.split('.').length -1])
}
});
var upload = multer({ //multer settings
storage: storage,
fileFilter: function (req, file, callback) {
var ext = path.extname(file.originalname);
if(ext !== '.png' && ext !== '.jpg' && ext !== '.gif' && ext !== '.jpeg') {
return callback(new Error('Only images are allowed'))
}
callback(null, true)
},
limits:{
fileSize: 1024 * 1024
}
}).single('profilepic');
摘自Node.js - File upload. The original authors were Iceman and Mikhail. Attribution details can be found on the contributor page. The source is licenced under CC BY-SA 3.0 and may be found in the Documentation archive。参考题目ID:4080 范例ID:14210.
这很有帮助,谢谢。在我的例子中,我需要添加一个中间件以确保 JWToken 就位并使用 构建它XHR。如果其他人需要帮助,这对我有用。在 XHR header.
中传递令牌时可以轻松完成客户:
const loadHandler = event =>{
// loadHandler mandate
}
const errorHandler = event => {
// error mandate
}
const abortHandler = event => {
// abort mandate
}
const data = new FormData()
data.append('file', upFile)
var formData = new FormData();
var xhr = new window.XMLHttpRequest();
formData.append('files', upFile); // this is a state object set onChange
xhr.open('post', '/uploadFile', true);
xhr.setRequestHeader('token', thetoken); // Passing token in header
xhr.addEventListener("load", loadHandler, false);
xhr.addEventListener("error", errorHandler, false);
xhr.addEventListener("abort", abortHandler, false);
xhr.send(formData);
服务器
const express = require('express'),
app= express.Router(),
rf = require('./RoutFuctions');
...
app.post('/uploadFile', rf.verifyToken, function (req, res, next) {
// upload portion above
});
RoutFunctions.js
const jwt = require('jsonwebtoken')
const tokenTest = (token, res, jwt, caller, next) => {
jwt.verify(token, process.env.SECRET_KEY, err => {
if(err) {
res.sendStatus(403);
console.log('could not verify token');
} else {
console.log("token verified");
next(); // Next middleware
}
});
}
exports.verifyToken = function(req, res, next) {
if(req.body.token !== undefined) { // non upload scenario
var caller = ''
if(req.body.caller !== undefined) caller = req.body.caller;
tokenTest(req.body.token, res, jwt, caller, next)
} else { // attempt to extract token in XHR header upload scenario
if(req.headers.token !== undefined){
var token = req.headers.token
tokenTest(req.headers.token, res, jwt, caller, next)
} else {
res.sendStatus(403);
}
}
}
多个或单个文件的完整实施。
注意:对于单个文件使用 .single('filename') 或 .array('filename',1)
const express = require("express");
const app = express();
var session = require('express-session')
const multer = require("multer");
const path = require("path");
var storage = multer.diskStorage({ //multers disk storage settings
destination: function (req, file, cb) {
cb(null, path.join(__dirname,"uploads"))
},
filename: function (req, file, cb) {
var datetimestamp = Date.now();
cb(null, file.fieldname + '-' + datetimestamp + '.' + file.originalname.split('.')[file.originalname.split('.').length -1])
}
});
var upload = multer({ //multer settings
storage: storage,
fileFilter: function (req, file, callback) {
var ext = path.extname(file.originalname);
if(ext !== '.png' && ext !== '.jpg' && ext !== '.gif' && ext !== '.jpeg') {
return callback(new Error('Only images are allowed'))
}
callback(null, true)
},
limits:{
fileSize: 1024 * 1024
}
}).array('profile',2);
app.post("/upload", upload,(req, res) => {
res.json({
msg:"uploaded"
})
});
app.use((err,req,res,next)=>{
console.log(err.message);
res.status(404).json({
msg:err.message
})
})
app.listen(
8080,
(error) => {
if (error) {
console.log("error");
}
},
() => {
console.log("listening at port 8080");
}
);
注意:您可以通过扩展 Error 并在 err、req、res、next 块中发送自定义消息和状态来创建自己的自定义错误消息
我现在正在测试这个替代方案。对我来说似乎可行,但我仍在评估( 打字稿):
import crypto from 'crypto';
import multer, { FileFilterCallback } from 'multer';
import { resolve } from 'path';
const tmpFolder = resolve(__dirname, '..', '..', 'tmp');
const fileSize = 50 * 1024 * 1024;
export default {
tmpFolder,
fileFilter: (
request: Express.Request,
file: Express.Multer.File,
callback: FileFilterCallback,
) => {
const acceptedTypes = file.mimetype.split('/');
if (acceptedTypes[0] === 'image' || acceptedTypes[0] === 'video') {
callback(null, true);
} else {
callback(null, false);
callback(new Error('Only images and videos formats allowed!'));
}
},
limits: {
fileSize,
},
storage: multer.diskStorage({
destination: tmpFolder,
filename: (request, file, callback) => {
const fileHash = crypto.randomBytes(16).toString('hex');
const fileName = `${fileHash}-${file.originalname}`;
return callback(null, fileName);
},
}),
};