我有一个Express路由,它被设置为接受
multipart/formdata
文件并将其上传到S3桶。我正在使用
multer
来过滤图片类型,并通过创建一个
目录将它们暂时存储在服务器上。在上传成功后不久,这些文件就会被删除。根据multer的配置,文件数组被命名为
upload
,最多可接受3张图片。
images
该代码在我的本地机器上完美地工作。我通过POSTMAN测试,可以上传1-3个文件并得到正确的响应。如果没有附加文件,也会触发正确的响应,都是状态代码200。
完全相同的代码库用Docker部署在Amazon ECS上,但不知何故一直失败,状态码是500,而且是代码库中找不到的一般 "错误 "信息。使用日志,我已经确定multer不是原因,因为它通过了过滤器。它似乎是在multer中间件和路由本身之间的某个地方失败了,有一个例外。
异常情况。使用POSTMAN,如果一个
multipart/formdata
POST请求没有文件,即空的
数组,路由被正确触发,并返回信息 "你没有附加任何图像 "作为响应。
images
我一直无法解决这个问题,如果能在这个问题上提供一些指导,我将不胜感激!
CODE SNIPPETS。
filesController。
files.post(
"/multiple",
upload.array("images", 3),
async (req: ExpressRequest, res: ExpressResponse) => {
try {
const files: { [fieldname: string]: Express.Multer.File[] } | Express.Multer.File[] =
req.files;
console.log("FILES", files);
// execute only if there are files
if (files.length > 0) {
const dataPromises = (files as Array<Express.Multer.File>).map(
async (file: Express.Multer.File) => {
// check if file.mimetype here is 'image/heic', and convert into jpeg accordingly
const fileNameWithoutExt = file.filename.split(".")[0];
try {
if (file.mimetype == "image/heic") {
await convertFile(file, fileNameWithoutExt, 0.2);
const response = await uploadFilePath(
S3_IMAGE_BUCKET,
`./uploads/${fileNameWithoutExt}.jpeg`,
`${fileNameWithoutExt}.jpeg`
console.log("HEIC File Upload Response", response);
fs.unlinkSync(`./uploads/${fileNameWithoutExt}.jpeg`);
fs.unlinkSync(file.path);
return {
fileName: `${fileNameWithoutExt}.jpeg`,
metaData: response.$metadata,
} else {
const response = await uploadFile(S3_IMAGE_BUCKET, file);
console.log("JPEG File Upload Response", response);
fs.unlinkSync(file.path);
return {
fileName: file.filename,
metaData: response.$metadata,
} catch (err) {
console.error("Error for file conversion/upload", err, err.stack);
res.status(500).send({
message: "Upload failed due to conversion or something.",
error: err,
stack: err.stack,
const fileData = await Promise.all(dataPromises);
const fileNames = fileData.map((data: any) => data.fileName);
const statusCodes = fileData.map((data: any) => data.metaData.httpStatusCode);
if (statusCodes.find((statusCode) => statusCode === 200)) {
res.status(200).send({
filePath: `/image/`,
fileNames,
} else {
res.status(403).send({
message: "Upload failed. Please check credentials or file has been selected.",
} else {
res.status(200).send({
message: "You did not attach any images",
} catch (err) {
res.status(500).send({
message: "Upload failed. Please check credentials or file has been selected.",
multer配置。
const storage = multer.diskStorage({
// potential error, path to store files, callback
destination: (req, file, cb) => {
// cb acceptes two arguments: 1. err 2. destination folder wrt to server.js
cb(null, "uploads/");
filename: (req, file, cb) => {
console.log("MULTER STORAGE STARTED")
const date = new Date().toISOString().substring(0, 10);
// const name = `${req.body.first_name}_${req.body.last_name}`;
// cb defines the name of the file when stored
const alphabet = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-";
const nanoid = customAlphabet(alphabet, 20);
cb(null, `${date}_${nanoid()}_${file.originalname}`);
console.log("FILE NAME CREATED, MULTER STORAGE STOPPED")
/* Accept jpeg or png files only */
// NOTE: file type rejection works, but there is no error message displayed if file is rejected. logic in route continues to be executed
const fileFilter = (
req: Request,
file: Express.Multer.File,
cb: (error: Error | null, accepted: boolean) => void
) => {
console.log("======== FILE FILTER ========", file);
file.mimetype === "image/jpeg" ||
file.mimetype === "image/png" ||
file.mimetype === "image/heic"
cb(null, true);
console.log("FILTER PASSED")
} else {
console.log("FILTER FAILED");
cb(null, false);
/* Only accepts filesize up to 5MB */
// the first parameter is super important that determines where the data is stored on the server
const upload = multer({
dest: "uploads/", // default simple config to upload file as binary data
storage, // enable if storage of actual file is required.
// limits: { fileSize: 1024 * 1024 * 5 },
fileFilter,
屏幕截图。
在表格数据中没有图像的响应
表单数据中带有图像的响应
你能确保上传目录在你的Docker容器中存在吗?如果它不存在,Multer就不会创建它。它可能在你的
功能和实际写入文件到磁盘之间默默地失败。
storage
const storage = multer.diskStorage({ // potential error, path to store files, callback destination: (req, file, cb) => { // cb acceptes two arguments: 1. err 2. destination folder wrt to server.js cb(null, "uploads/");
应该是这样的。