node.js - node express with multer 如何在运行时选择 MemoryStorage 或 DiskStorage
问题描述
您好我正在尝试在运行时选择存储,因为我还添加了一个中间件来获取之前的内容大小。
我在其他地方有一个导出的枚举:
export enum Storage {
DISK,
MEMORY
}
中间件 checkHeader :
const checkHeader = (req :any , res: any , next:any ) => {
console.log('content-length :',req.headers['content-length']);
const sizeContent = req.headers['content-length'];
if (!sizeContent || Number(sizeContent) ==0 ) {
res.send(400).end();
return;
}
const sizeKo = Number(sizeContent)/1024 >5000 ;
console.log('size : (KO) ',sizeKo);
res.locals.storage = Number(sizeContent)/1024 >5000 ? Storage.DISK:Storage.MEMORY;
next();
};
制作multer中间件
const createUpload = (_req: Request, res: Response, _next:any) :any =>{
let storage;
if (res.locals) {console.log('in createupload : ' , res.locals.storage);}
else return _next;
if (res.locals.storage === Storage.DISK){
storage = multer.diskStorage({
destination: function (_req, _file, cb) {
cb(null, './uploads/');
},
filename: function (_req: any, file: any, cb: any) {
cb(null, file.originalname);
},
});
}
else {
storage = multer.memoryStorage();
}
return multer({ storage: storage, fileFilter: fileFilter }).any();
};
创建路线
const router = express
.Router()
.get('/', controller.all)
.post('/', controller.create)
.get('/:id', controller.byId)
.get('/:id/contractors', controller.getContractors)
.post('/:id/contractors', controller.addContractors)
.post('/:id/documents', checkHeader ,createUpload, controller.addDocument);
它不起作用,我想这是因为 createUpload 不返回,即示例,
multer({storage : multer.memoryStorage()}).any()
但它返回返回它的函数!但是我不得不把它写成一个中间件函数,即 (req,res,next)=>return
一个中间件,以便让它通过中间件链....
我不知道如何为这个用例编写代码,...
预先感谢
解决方案
最后,我得到了一个解决方法:
const fileFilter = (_req: any, file: any, cb: any) => {
if (
file.mimetype === 'image/jpg' ||
file.mimetype === 'image/jpeg' ||
file.mimetype === 'image/png' ||
file.mimetype === 'application/pdf'
) {
cb(null, true);
} else {
cb(new Error('not type pdf or jpg/jpeg or png'), false);
}
};
const setUploadDest = (req :any , res: any , next:any ) => {
console.log('content-length :',req.headers['content-length']);
const sizeContent = req.headers['content-length'];
res.locals.storage = Number(sizeContent)/1024 >5000 ? Storage.DISK:Storage.MEMORY;
next();
};
const skipMemory = (_req :any , res: any , next:any ) => {
if (res.locals.storage !== Storage.MEMORY){
next('route');
}
else next();
};
const skipDisk = (_req :any , res: any , next:any ) => {
if (res.locals.storage !== Storage.DISK){
next('route');
}
else next();
};
const diskStorage = multer.diskStorage({
destination: function (_req, _file, cb) {
cb(null, './uploads/');
},
filename: function (_req: any, file: any, cb: any) {
cb(null, file.originalname);
}
});
const router = express
.Router()
.get('/', controller.all)
.post('/', controller.create)
.get('/:id', controller.byId)
.get('/:id/contractors', controller.getContractors)
.post('/:id/contractors', controller.addContractors)
.use('/:id/documents',setUploadDest)
.post('/:id/documents', skipMemory , multer({storage : multer.memoryStorage(), fileFilter:fileFilter}).any() , controller.addDocument)
.post('/:id/documents', skipDisk, multer({storage : diskStorage, fileFilter :fileFilter}).any() , controller.addDocument);
意味着我复制了后路由器,每个都附加到一个 multer 存储构造函数。我通过添加一个“跳过”中间件来控制路由,如果存储条件不满足,它将发送到另一条路由......
推荐阅读
- c++ - 如何快速检查瓷砖网格中的元素是否在我的视口中?
- bash - 在后台运行时杀死进程的bash脚本
- python - 如何使此命令显示机器人正在服务的用户数量?
- python - 使用 python (pandas?) 对新数据进行重复排序
- php - 喜欢和不喜欢系统数据库和查询问题?
- javascript - 在我的网页上在小屏幕上运行另一个 .html 页面
- python - 更改 Pandas 中列的值
- php - Imagemagick 从 6.9 升级到 7 后反转颜色
- hive - 如何向这个 hive 命令添加一个表?
- module - 有没有办法获取包含在 fortran .mod 文件中的符号?