使用没有中间件功能的multer上传到S3
Upload to S3 using multer without a middleware function
我正在使用 multer 将媒体上传到我的 s3 存储桶。我正在使用 multer-s3 作为中间件来上传媒体,例如:
const upload = multer({
storage: multerS3({
s3: s3,
bucket: myBucket,
key: function (req, file, cb) {
cb(null, new Date().getTime() + '_' + file.originalname)
}
})
});
并在路由中调用它:
router.post("/media",upload.single("media"))
效果很好。但是一个不适合我的场景是:假设我上传了一张图片,我想通过在上传之前调整它的大小来存储它的多个版本。我无法像正常那样调用上传功能。我想做类似的事情:
let thumbnail = myFunctionToReturnImageFile(req.file);
upload(thumbnail);
我知道我需要发送一些 multi-part/form-part 但我找不到解决方案。如果你给我推荐一些东西会很棒。
您可以尝试使用 Node.js 图片处理,例如 sharp
调整大小,然后上传到 S3。
sharp(req.file)
.resize(320, 240)
.toBuffer()
.then(thumbnail => { upload(thumbnail) })
.catch( err => { ... });
Multer 是一个 busboy 包装器。您可以使用 busboy 而不是 multer 来处理请求并进行所需的所有操作。
const Busboy = require('busboy');
router.post('/media', function(req, res) {
var busboy = new Busboy({ headers: req.headers });
busboy.on('file', function(fieldname, file, filename, encoding, mimetype) {
console.log('File ' + filename + ' upload incoming');
file.on('end', function() {
console.log('File ' + filename + ' upload finished');
// make all you want, eg:
let thumbnail = myFunctionToReturnImageFile(file);
upload(thumbnail);
res.send('file uploaded');
});
});
});
选项 1 - 使用 multer-s3-transform middleware to handle S3 upload with file transformations, like image resizing using sharp.
const multer = require('multer')
const multerS3 = require('multer-s3-transform')
const sharp = require('sharp')
const AWS = require('aws-sdk')
const S3 = new AWS.S3({
accessKeyId: ...,
secretAccessKey: ...
})
const upload = multer({
storage: multerS3({
s3: S3,
bucket: ...,
shouldTransform: true,
transforms: [
{
id: 'original',
key: (req, file, cb) => cb(null, new Date().getTime() + '_' + req.file.originalname),
transform: (req, file, cb) => cb(null, sharp().jpg())
},
{
id: 'large',
key: (req, file, cb) => cb(null, new Date().getTime() + '_large_' + req.file.originalname),
transform: (req, file, cb) => cb(null, sharp().resize(1200, 900).jpg())
},
{
id: 'small',
key: (req, file, cb) => cb(null, new Date().getTime() + '_small_' + req.file.originalname),
transform: (req, file, cb) => cb(null, sharp().resize(400, 300).jpg())
}
]
})
})
router.post('/media', upload.single('media'))
选项 2 - 如果您坚持手动操作,您可以使用普通 multer
来处理传入文件,使用 sharp
调整大小并使用 AWS-SDK
.
将每个调整大小的文件上传到 S3
const multer = require('multer')
const sharp = require('sharp')
const AWS = require('aws-sdk')
const S3 = new AWS.S3({
accessKeyId: ...,
secretAccessKey: ...
})
router.post('/media', multer().single('media'), (req, res) => {
// req.file represents the uploaded file
let time = new Date().getTime()
Promise.all([
// original file
S3.upload({
Bucket: ...,
Key: time + '_' + req.file.originalname,
Body: req.file.buffer
}),
// large preview
sharp(req.file)
.resize(1200, 900)
.toBuffer()
.then(resized => S3.upload({
Bucket: ...,
Key: time + '_large_' + req.file.originalname,
Body: resized
}).promise()),
// small thumbnail
sharp(req.file)
.resize(400, 300)
.toBuffer()
.then(resized => S3.upload({
Bucket: ...,
Key: time + '_small_' + req.file.originalname,
Body: resized
}).promise()),
])
.then(() => res.send("Images uploaded"))
.catch(e => {
console.warn(e) // debug this error
res.status(500).send("Unable to upload images")
})
})
我正在使用 multer 将媒体上传到我的 s3 存储桶。我正在使用 multer-s3 作为中间件来上传媒体,例如:
const upload = multer({
storage: multerS3({
s3: s3,
bucket: myBucket,
key: function (req, file, cb) {
cb(null, new Date().getTime() + '_' + file.originalname)
}
})
});
并在路由中调用它:
router.post("/media",upload.single("media"))
效果很好。但是一个不适合我的场景是:假设我上传了一张图片,我想通过在上传之前调整它的大小来存储它的多个版本。我无法像正常那样调用上传功能。我想做类似的事情:
let thumbnail = myFunctionToReturnImageFile(req.file);
upload(thumbnail);
我知道我需要发送一些 multi-part/form-part 但我找不到解决方案。如果你给我推荐一些东西会很棒。
您可以尝试使用 Node.js 图片处理,例如 sharp
调整大小,然后上传到 S3。
sharp(req.file)
.resize(320, 240)
.toBuffer()
.then(thumbnail => { upload(thumbnail) })
.catch( err => { ... });
Multer 是一个 busboy 包装器。您可以使用 busboy 而不是 multer 来处理请求并进行所需的所有操作。
const Busboy = require('busboy');
router.post('/media', function(req, res) {
var busboy = new Busboy({ headers: req.headers });
busboy.on('file', function(fieldname, file, filename, encoding, mimetype) {
console.log('File ' + filename + ' upload incoming');
file.on('end', function() {
console.log('File ' + filename + ' upload finished');
// make all you want, eg:
let thumbnail = myFunctionToReturnImageFile(file);
upload(thumbnail);
res.send('file uploaded');
});
});
});
选项 1 - 使用 multer-s3-transform middleware to handle S3 upload with file transformations, like image resizing using sharp.
const multer = require('multer')
const multerS3 = require('multer-s3-transform')
const sharp = require('sharp')
const AWS = require('aws-sdk')
const S3 = new AWS.S3({
accessKeyId: ...,
secretAccessKey: ...
})
const upload = multer({
storage: multerS3({
s3: S3,
bucket: ...,
shouldTransform: true,
transforms: [
{
id: 'original',
key: (req, file, cb) => cb(null, new Date().getTime() + '_' + req.file.originalname),
transform: (req, file, cb) => cb(null, sharp().jpg())
},
{
id: 'large',
key: (req, file, cb) => cb(null, new Date().getTime() + '_large_' + req.file.originalname),
transform: (req, file, cb) => cb(null, sharp().resize(1200, 900).jpg())
},
{
id: 'small',
key: (req, file, cb) => cb(null, new Date().getTime() + '_small_' + req.file.originalname),
transform: (req, file, cb) => cb(null, sharp().resize(400, 300).jpg())
}
]
})
})
router.post('/media', upload.single('media'))
选项 2 - 如果您坚持手动操作,您可以使用普通 multer
来处理传入文件,使用 sharp
调整大小并使用 AWS-SDK
.
const multer = require('multer')
const sharp = require('sharp')
const AWS = require('aws-sdk')
const S3 = new AWS.S3({
accessKeyId: ...,
secretAccessKey: ...
})
router.post('/media', multer().single('media'), (req, res) => {
// req.file represents the uploaded file
let time = new Date().getTime()
Promise.all([
// original file
S3.upload({
Bucket: ...,
Key: time + '_' + req.file.originalname,
Body: req.file.buffer
}),
// large preview
sharp(req.file)
.resize(1200, 900)
.toBuffer()
.then(resized => S3.upload({
Bucket: ...,
Key: time + '_large_' + req.file.originalname,
Body: resized
}).promise()),
// small thumbnail
sharp(req.file)
.resize(400, 300)
.toBuffer()
.then(resized => S3.upload({
Bucket: ...,
Key: time + '_small_' + req.file.originalname,
Body: resized
}).promise()),
])
.then(() => res.send("Images uploaded"))
.catch(e => {
console.warn(e) // debug this error
res.status(500).send("Unable to upload images")
})
})