使用 multer 将多个图像上传到 AWS S3
Uploading multiple images with multer to AWS S3
我目前有一个后端,我可以在其中使用 multer 上传多张图片。这些图像通过 sharp 传递以调整图像大小以创建完整和缩略图图像。 post 的条目存储在我的数据库中的 posts table 中,图像的文件名也存储在我的数据库中的 Post_Images table 中.
我的问题是我目前正在使用 multer diskStorage 将图像存储在我的磁盘上,现在我想将图像存储在 AWS S3 上。
我试图实现这个,但没有成功。
posts.js
const s3 = new AWS.S3({
accessKeyId: process.env.AWS_ID,
secretAccessKey: process.env.AWS_SECRET
Bucket:process.env.AWS_BUCKET
})
const storage = multer.diskStorage({
destination: function (req, file, callback) {
callback(null, "./uploads");
},
filename: function (req, file, callback) {
console.log(file.originalname);
callback(null, file.originalname + "-" + new Date().toISOString() + "-" + uuidv4());
},
});
const multerS3Config = multerS3({
s3: s3,
bucket: process.env.AWS_BUCKET,
metadata: function (req, file, cb) {
cb(null, { fieldName: file.fieldname });
},
key: function (req, file, cb) {
console.log(file)
// cb(null, file.originalname + "-" + new Date().toISOString() + "-" + uuidv4())//
cb(null, new Date().toISOString() + "-" + uuidv4()+ "-" + file.originalname)
}
});
const upload = multer({
storage: multerS3Config,
limits: { fieldSize: 25 * 1024 * 1024 },
});
router.post(
"/",
[
upload.array("images", config.get("maxImageCount")),
imageResize,
],
async (req, res) => {
const paths = await req.files.map((file) => ({ fileName: file.filename }));
await Post.create({
title: req.body.title,
userId: req.body.userId,
Post_Images: paths.map((x) => ({ images: x.fileName
})),
},
{
include: [Post_Image] }).then(
res.status(201).send()
ImageResize.js
const sharp = require("sharp");
const path = require("path");
const fs = require("fs");
const outputFolder = "public/assets";
module.exports = async (req, res, next) => {
const images = [];
const resizePromises = req.files.map(async (file) => {
await sharp(file.path)
.resize(2000)
.jpeg({ quality: 50 })
.toFile(path.resolve(outputFolder, file.filename + "_full.jpg"));
await sharp(file.path)
.resize(100)
.jpeg({ quality: 30 })
.toFile(path.resolve(outputFolder, file.filename + "_thumb.jpg"));
fs.unlinkSync(file.path);
images.push(file.filename);
});
await Promise.all([...resizePromises]);
req.images = images;
next();
};
每次我尝试上传 post,我总是收到
UnhandledPromiseRejectionWarning: Error: Invalid input
我想我收到这个错误是因为我不再使用我的磁盘存储,因此我无法访问 file.path 和 file.filename。
当我在 ImageREsize.js 中间件中执行 console.log(file) 时,我得到这个
{ fieldname: 'images', originalname: 'FILENAME', encoding: '7bit',
mimetype: 'image/jpeg', size: 38184, bucket: 'BUCKET NAME', key:
'IMAGE NAME', acl: 'private', contentType: 'application/octet-
stream', contentDisposition: null, storageClass: 'STANDARD',
serverSideEncryption: null, metadata: { fieldName: 'images' },
location: 'IMAGE LINK', etag: '""', versionId: undefined }
更新
最初我尝试使用 multerS3 来完成此操作,但在查看了几个答案后我决定尝试一下。要使用普通 multer 处理传入文件,请使用 sharp 调整其大小并使用 AWS-SDK 将每个调整大小的文件上传到 S3。
图像条目正在存储在我的 postgres 数据库中,但随后我得到一个
Error: Input file is missing
当我检查我的桶时,它是空的。
这是我的代码
posts.js
const s3 = new AWS.S3({
accessKeyId: process.env.AWS_ID,
secretAccessKey: process.env.AWS_SECRET,
Bucket:process.env.AWS_BUCKET,
region:process.env.AWS_REGION
})
const storage=multer.memoryStorage({})
const upload = multer({
storage: storage,
limits: { fieldSize: 25 * 1024 * 1024 },
});
router.post(
"/",
[ upload.array("images", config.get("maxImageCount")),
imageResize,
],
async (req, res) => {
const paths = await req.files.map((file) => ({ originalName:
file.originalname + "-" + new Date().toISOString() + "-" + uuidv4()
}));
await Post.create({
title: req.body.title,
userId: req.body.userId,
Post_Images: paths.map((x) => ({ images: x.originalName
})),
},
{
include: [Post_Image] }).then(
res.status(201).send()
imageResize.js
const sharp = require("sharp");
const path = require("path");
const fs = require("fs");
const outputFolder = "public/assets";
require("dotenv").config();
const AWS = require('aws-sdk')
const s3 = new AWS.S3({
accessKeyId: process.env.AWS_ID,
secretAccessKey: process.env.AWS_SECRET,
Bucket:process.env.AWS_BUCKET,
region:process.env.AWS_REGION
})
module.exports = async (req, res, next) => {
const images = [];
const resizePromises = req.files.map(async (file) => {
console.log(file)
await sharp(file)
.resize(2000)
.jpeg({ quality: 50 })
.toBuffer()
.then(resized=>s3.upload({
Bucket:process.env.AWS_BUCKET,
key:file.originalname + "-" + new Date().toISOString() + "-" + uuidv4() + "_full.jpg",
Body:resized
}));
await sharp(file)
.resize(100)
.jpeg({ quality: 30 })
.toBuffer()
.then(resized=>s3.upload({
Bucket:process.env.AWS_BUCKET,
key:file.originalname + "-" + new Date().toISOString() + "-" + uuidv4() + "_thumb.jpg",
Body:resized
}));
fs.unlinkSync(file.buffer);
images.push(file.originalname);
});
await Promise.all([...resizePromises]);
req.images = images;
next();
};
我设法让它工作,我的问题是我的 imageResize 中间件。我必须将存储到 AWS S3 的代码存储到我拥有的代码中,而不是将其保存到磁盘中。
posts.js
const storage=multer.memoryStorage()
const upload = multer({
storage: storage,
limits: { fieldSize: 25 * 1024 * 1024 },
});
router.post(
"/",
[ upload.array("images", config.get("maxImageCount")),
imageResize,
],
async (req, res) => {
const paths = await req.files.map((file) => ({ originalName: file.originalname}));
await Post.create({
title: req.body.title,
userId: req.body.userId,
Post_Images: paths.map((x) => ({ images: x.originalName })),
},
{
include: [Post_Image] }).then(
res.status(201).send())
imageResize.js
const sharp = require("sharp");
require("dotenv").config();
const AWS = require('aws-sdk')
const s3 = new AWS.S3({
accessKeyId: process.env.AWS_ID,
secretAccessKey: process.env.AWS_SECRET,
region:process.env.AWS_REGION
})
module.exports = async (req, res, next) => {
const images = [];
const resizePromises = req.files.map(async (file) => {
console.log(file)
await sharp(file.buffer)
.resize(2000)
.jpeg({ quality: 50 })
.toBuffer()
.then(resized=>s3.upload({
Bucket:process.env.AWS_BUCKET,
Key:file.originalname + "_full.jpg",
Body:file.buffer,
ACL: 'public-read'
}).promise()),
await sharp(file.buffer)
.resize(100)
.jpeg({ quality: 30 })
.toBuffer()
.then(resized=>s3.upload({
Bucket:process.env.AWS_BUCKET,
Key:file.originalname + "_thumb.jpg",
Body:file.buffer,
ACL: 'public-read'
}).promise())
images.push(file.originalname);
});
await Promise.all([...resizePromises]);
req.images = images;
next();
};
我目前有一个后端,我可以在其中使用 multer 上传多张图片。这些图像通过 sharp 传递以调整图像大小以创建完整和缩略图图像。 post 的条目存储在我的数据库中的 posts table 中,图像的文件名也存储在我的数据库中的 Post_Images table 中.
我的问题是我目前正在使用 multer diskStorage 将图像存储在我的磁盘上,现在我想将图像存储在 AWS S3 上。
我试图实现这个,但没有成功。
posts.js
const s3 = new AWS.S3({
accessKeyId: process.env.AWS_ID,
secretAccessKey: process.env.AWS_SECRET
Bucket:process.env.AWS_BUCKET
})
const storage = multer.diskStorage({
destination: function (req, file, callback) {
callback(null, "./uploads");
},
filename: function (req, file, callback) {
console.log(file.originalname);
callback(null, file.originalname + "-" + new Date().toISOString() + "-" + uuidv4());
},
});
const multerS3Config = multerS3({
s3: s3,
bucket: process.env.AWS_BUCKET,
metadata: function (req, file, cb) {
cb(null, { fieldName: file.fieldname });
},
key: function (req, file, cb) {
console.log(file)
// cb(null, file.originalname + "-" + new Date().toISOString() + "-" + uuidv4())//
cb(null, new Date().toISOString() + "-" + uuidv4()+ "-" + file.originalname)
}
});
const upload = multer({
storage: multerS3Config,
limits: { fieldSize: 25 * 1024 * 1024 },
});
router.post(
"/",
[
upload.array("images", config.get("maxImageCount")),
imageResize,
],
async (req, res) => {
const paths = await req.files.map((file) => ({ fileName: file.filename }));
await Post.create({
title: req.body.title,
userId: req.body.userId,
Post_Images: paths.map((x) => ({ images: x.fileName
})),
},
{
include: [Post_Image] }).then(
res.status(201).send()
ImageResize.js
const sharp = require("sharp");
const path = require("path");
const fs = require("fs");
const outputFolder = "public/assets";
module.exports = async (req, res, next) => {
const images = [];
const resizePromises = req.files.map(async (file) => {
await sharp(file.path)
.resize(2000)
.jpeg({ quality: 50 })
.toFile(path.resolve(outputFolder, file.filename + "_full.jpg"));
await sharp(file.path)
.resize(100)
.jpeg({ quality: 30 })
.toFile(path.resolve(outputFolder, file.filename + "_thumb.jpg"));
fs.unlinkSync(file.path);
images.push(file.filename);
});
await Promise.all([...resizePromises]);
req.images = images;
next();
};
每次我尝试上传 post,我总是收到
UnhandledPromiseRejectionWarning: Error: Invalid input
我想我收到这个错误是因为我不再使用我的磁盘存储,因此我无法访问 file.path 和 file.filename。
当我在 ImageREsize.js 中间件中执行 console.log(file) 时,我得到这个
{ fieldname: 'images', originalname: 'FILENAME', encoding: '7bit',
mimetype: 'image/jpeg', size: 38184, bucket: 'BUCKET NAME', key:
'IMAGE NAME', acl: 'private', contentType: 'application/octet-
stream', contentDisposition: null, storageClass: 'STANDARD',
serverSideEncryption: null, metadata: { fieldName: 'images' },
location: 'IMAGE LINK', etag: '""', versionId: undefined }
更新
最初我尝试使用 multerS3 来完成此操作,但在查看了几个答案后我决定尝试一下。要使用普通 multer 处理传入文件,请使用 sharp 调整其大小并使用 AWS-SDK 将每个调整大小的文件上传到 S3。
图像条目正在存储在我的 postgres 数据库中,但随后我得到一个
Error: Input file is missing
当我检查我的桶时,它是空的。
这是我的代码
posts.js
const s3 = new AWS.S3({
accessKeyId: process.env.AWS_ID,
secretAccessKey: process.env.AWS_SECRET,
Bucket:process.env.AWS_BUCKET,
region:process.env.AWS_REGION
})
const storage=multer.memoryStorage({})
const upload = multer({
storage: storage,
limits: { fieldSize: 25 * 1024 * 1024 },
});
router.post(
"/",
[ upload.array("images", config.get("maxImageCount")),
imageResize,
],
async (req, res) => {
const paths = await req.files.map((file) => ({ originalName:
file.originalname + "-" + new Date().toISOString() + "-" + uuidv4()
}));
await Post.create({
title: req.body.title,
userId: req.body.userId,
Post_Images: paths.map((x) => ({ images: x.originalName
})),
},
{
include: [Post_Image] }).then(
res.status(201).send()
imageResize.js
const sharp = require("sharp");
const path = require("path");
const fs = require("fs");
const outputFolder = "public/assets";
require("dotenv").config();
const AWS = require('aws-sdk')
const s3 = new AWS.S3({
accessKeyId: process.env.AWS_ID,
secretAccessKey: process.env.AWS_SECRET,
Bucket:process.env.AWS_BUCKET,
region:process.env.AWS_REGION
})
module.exports = async (req, res, next) => {
const images = [];
const resizePromises = req.files.map(async (file) => {
console.log(file)
await sharp(file)
.resize(2000)
.jpeg({ quality: 50 })
.toBuffer()
.then(resized=>s3.upload({
Bucket:process.env.AWS_BUCKET,
key:file.originalname + "-" + new Date().toISOString() + "-" + uuidv4() + "_full.jpg",
Body:resized
}));
await sharp(file)
.resize(100)
.jpeg({ quality: 30 })
.toBuffer()
.then(resized=>s3.upload({
Bucket:process.env.AWS_BUCKET,
key:file.originalname + "-" + new Date().toISOString() + "-" + uuidv4() + "_thumb.jpg",
Body:resized
}));
fs.unlinkSync(file.buffer);
images.push(file.originalname);
});
await Promise.all([...resizePromises]);
req.images = images;
next();
};
我设法让它工作,我的问题是我的 imageResize 中间件。我必须将存储到 AWS S3 的代码存储到我拥有的代码中,而不是将其保存到磁盘中。
posts.js
const storage=multer.memoryStorage()
const upload = multer({
storage: storage,
limits: { fieldSize: 25 * 1024 * 1024 },
});
router.post(
"/",
[ upload.array("images", config.get("maxImageCount")),
imageResize,
],
async (req, res) => {
const paths = await req.files.map((file) => ({ originalName: file.originalname}));
await Post.create({
title: req.body.title,
userId: req.body.userId,
Post_Images: paths.map((x) => ({ images: x.originalName })),
},
{
include: [Post_Image] }).then(
res.status(201).send())
imageResize.js
const sharp = require("sharp");
require("dotenv").config();
const AWS = require('aws-sdk')
const s3 = new AWS.S3({
accessKeyId: process.env.AWS_ID,
secretAccessKey: process.env.AWS_SECRET,
region:process.env.AWS_REGION
})
module.exports = async (req, res, next) => {
const images = [];
const resizePromises = req.files.map(async (file) => {
console.log(file)
await sharp(file.buffer)
.resize(2000)
.jpeg({ quality: 50 })
.toBuffer()
.then(resized=>s3.upload({
Bucket:process.env.AWS_BUCKET,
Key:file.originalname + "_full.jpg",
Body:file.buffer,
ACL: 'public-read'
}).promise()),
await sharp(file.buffer)
.resize(100)
.jpeg({ quality: 30 })
.toBuffer()
.then(resized=>s3.upload({
Bucket:process.env.AWS_BUCKET,
Key:file.originalname + "_thumb.jpg",
Body:file.buffer,
ACL: 'public-read'
}).promise())
images.push(file.originalname);
});
await Promise.all([...resizePromises]);
req.images = images;
next();
};