我第一次在 Node.js 和 Multer 库中处理多个文件。我有多个文件路径。例如员工信息、产品等。有些路径有一个输入文件字段,但有些路径有两个以上的输入文件字段。
条件句:
1. I should handle the files into the best suitable directory,
2. Rename each file to unique name in the directory.
3. Return each new name to the main function to record into database and reusable.
这是我尝试过的。我还附上了 git 项目的链接,包括请求图像的示例。
git 项目: https://github.com/Kicks-Me/multer-file-handle.git
import * as multer from 'multer';
import path from 'path';
import { fileURLToPath } from 'url';
import fs from 'fs';
import { v4 as uuidv4 } from 'uuid';
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
const mimeTypes = {
"image/png":"png",
"image/jpeg":"jpg",
"image/jpg":"jpg",
"image/gif":"gif",
"video/mp4":"mp4",
"audio/mpeg":"mp3",
"audio/wav":"wav",
"application/pdf":"pdf",
"application/vnd.ms-excel":"xls",
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet":"xlsx"
};
const accessFilePath = (fileType, reqpath) => {
let dest = "";
let pathType = "uploads/Others";
if(reqpath === "/location")
{
pathType = "uploads/locations";
}
else if(reqpath === "/employee")
{
pathType = "uploads/employees";
}
else if(reqpath === "/product")
{
pathType = "uploads/products";
}
dest =
mimeTypes[fileType] === "mp4"
? path.join(__dirname, "..", pathType, "video")
: mimeTypes[fileType] === "pdf"
? path.join(__dirname, "..", pathType, "documents", "pdf")
: mimeTypes[fileType] === "xls" || mimeTypes[fileType] === "xlsx"
? path.join(__dirname, "..", pathType, "documents", "excel")
: mimeTypes[fileType] === "mp3" || mimeTypes[fileType] === "wav"
? path.join(__dirname, "..", pathType, "audio")
: mimeTypes[fileType] === "gif"
? path.join(__dirname, "..", pathType, "gif")
: path.join(__dirname, "..", pathType, "image");
return dest;
};
const multerConfig = {
storage: multer.diskStorage({
destination: (req, file, callback) => {
let dest = "";
const fileType = file.mimetype;
dest = accessFilePath(fileType, req?.path);
if (!fs.existsSync(dest)) {
fs.mkdirSync(dest, { recursive: true });
}
callback(null, dest);
},
filename: (req, file, callback) => {
const ext = mimeTypes[file.mimetype];
callback(null, `${uuidv4()}.${ext}`);
},
}),
fileFilter: (req, file, callback) => {
const ext = mimeTypes[file.mimetype];
ext === "png" ||
ext === "jpg" ||
ext === "gif" ||
ext === "wav" ||
ext === "mp3" ||
ext === "wav" ||
ext === "mp4" ||
ext === "pdf" ||
ext === "xls" ||
ext === "xlsx"
? callback(null, true)
: callback(null, false);
},
};
export const upload = multer.default(multerConfig);
// Middleware to handle multiple files with different keys
export const handleMultipleFiles = (req, res, next) => {
const newImages = {};
// Process files attached to 'Profile' key
if (req.file) {
newImages.profile = req.file.filename;
}
// Process files attached to 'qr' key
if (req.files && req.files.length > 0) {
newImages.qr = req.files.map((file) => file.filename);
}
req.newImages = newImages;
next();
};
这是路线
import Route from 'express';
import { verifyJWT } from '../helper/jwt.js';
import { handleMultipleFiles, upload } from '../helper/multer.js';
const route = Route();
route.post('/upload',verifyJWT, upload.single('Profile'), upload.array('Images', 5),
handleMultipleFiles, (req, res) => {
const profileImage = req.newImages.profile;
const qrImages = req.newImages.qr;
return res.json({ profileImage, qrImages });
});
export default route;
从上面的代码中,我遇到了一些错误:
MulterError: Unexpected field
at wrappedFileFilter (/Users/tplussmacbookpro2/Desktop/kkkk/file-
handle/node_modules/multer/index.js:40:19)
at Multipart.<anonymous> (/Users/tplussmacbookpro2/Desktop/kkkk/file-
handle/node_modules/multer/lib/make-middleware.js:107:7)
at Multipart.emit (node:events:514:28)
at HeaderParser.cb (/Users/tplussmacbookpro2/Desktop/kkkk/file-
handle/node_modules/busboy/lib/types/multipart.js:358:14)
您可以在 github 中查看随附的项目以了解更多详细信息。
提前谢谢您。
上传多个可选字段可以使用 .fields 方法来处理。
因此,设置用于处理的字段名称:
upload.fields([
{
name: 'Profile'
maxCount: 1,
},
{
name: 'Images',
maxCount: 5,
},
])
然后,
req.files
将包含具有相应字段名的对象(如果提供,如果没有,该属性将不存在),例如,如果两个字段名都存在:
// req.files
{
Images: [file1, file2..],
Profile: [file]
}
因此在文件处理程序中,您只需检查这些字段名是否存在,并相应地分配文件名:
// Process files attached to 'Profile' key
if(req.files.Profile) {
newImages.profile = req.files.Profile[0].filename;
}
// Process files attached to 'qr' key
if(req.files.Images) {
newImages.qr = req.files.Images.map((file) => file.filename);
}
完整修改代码:
路线:
route.post('/upload',verifyJWT, upload.fields([
{
name: 'Profile'
maxCount: 1,
},
{
name: 'Images',
maxCount: 5,
},
]), handleMultipleFiles, (req, res) => {
const profileImage = req.newImages.profile;
const qrImages = req.newImages.qr;
return res.json({ profileImage, qrImages });
});
处理者:
// Middleware to handle multiple files with different keys
export const handleMultipleFiles = (req, res, next) => {
const newImages = {};
// Process files attached to 'Profile' key
if(req.files.Profile) {
newImages.profile = req.files.Profile[0].filename;
}
// Process files attached to 'qr' key
if(req.files.Images) {
newImages.qr = req.files.Images.map((file) => file.filename);
}
req.newImages = newImages;
next();
};