问题
I am trying to upload an image to amazon s3 using multer-s3
, but I am getting this error:
TypeError: Expected opts.s3 to be object node_modules/multer-s3/index.js:69:20
This is my server code:
var upload = multer({
storage: s3({
dirname: '/',
bucket: 'bucket',
secretAccessKey: 'key',
accessKeyId: 'key',
region: 'us-west-2',
filename: function (req, file, cb) {
cb(null, file.originalname);
}
})
});
app.post('/upload', upload.array('file'), function (req, res, next) {
res.send("Uploaded!");
});
Why I am getting this error?
回答1:
Complete and working Node Cheat | Upload to s3 using multer-s3 available.
Code:
var express = require('express'),
aws = require('aws-sdk'),
bodyParser = require('body-parser'),
multer = require('multer'),
multerS3 = require('multer-s3');
aws.config.update({
secretAccessKey: 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX',
accessKeyId: 'XXXXXXXXXXXXXXX',
region: 'us-east-1'
});
var app = express(),
s3 = new aws.S3();
app.use(bodyParser.json());
var upload = multer({
storage: multerS3({
s3: s3,
bucket: 'bucket-name',
key: function (req, file, cb) {
console.log(file);
cb(null, file.originalname); //use Date.now() for unique file keys
}
})
});
//open in browser to see upload form
app.get('/', function (req, res) {
res.sendFile(__dirname + '/index.html');//index.html is inside node-cheat
});
//use by upload form
app.post('/upload', upload.array('upl',1), function (req, res, next) {
res.send("Uploaded!");
});
app.listen(3000, function () {
console.log('Example app listening on port 3000!');
});
For complete repo:
Clone node-cheat express_multer_s3, run node app
followed by npm install express body-parser aws-sdk multer multer-s3
.
Happy Helping!
回答2:
@V31 has answered very well still I want to add my 2 cents.
I believe in keeping one responsibility into one file, for better code organization and debugging purpose.
I have created a file for uploading upload.js
.
require('dotenv').config();
const AWS = require('aws-sdk');
const multer = require('multer');
const multerS3 = require('multer-s3');
const s3Config = new AWS.S3({
accessKeyId: process.env.AWS_IAM_USER_KEY,
secretAccessKey: process.env.AWS_IAM_USER_SECRET,
Bucket: process.env.AWS_BUCKET_NAME
});
const fileFilter = (req, file, cb) => {
if (file.mimetype === 'image/jpeg' || file.mimetype === 'image/png') {
cb(null, true)
} else {
cb(null, false)
}
}
// this is just to test locally if multer is working fine.
const storage = multer.diskStorage({
destination: (req, res, cb) => {
cb(null, 'src/api/media/profiles')
},
filename: (req, file, cb) => {
cb(null, new Date().toISOString() + '-' + file.originalname)
}
})
const multerS3Config = multerS3({
s3: s3Config,
bucket: process.env.AWS_BUCKET_NAME,
metadata: function (req, file, cb) {
cb(null, { fieldName: file.fieldname });
},
key: function (req, file, cb) {
console.log(file)
cb(null, new Date().toISOString() + '-' + file.originalname)
}
});
const upload = multer({
storage: multerS3Config,
fileFilter: fileFilter,
limits: {
fileSize: 1024 * 1024 * 5 // we are allowing only 5 MB files
}
})
exports.profileImage = upload;
Which is imported inside my routes routes.js
const express = require('express');
const ProfileController = require('../profile/controller');
const { profileImage } = require('../utils/upload.js');
const routes = (app) => {
const apiRoutes = express.Router();
apiRoutes.use('/profile', profileRoutes);
profileRoutes.post('/',profileImage.single('profileImage'), ProfileController.saveProfile);
app.use('/api', apiRoutes);
}
module.exports = routes
Postman screen shot for post body
回答3:
s3
needs to be an object to be passed. According to the docs, the object needs to be like this:
var upload = multer({
storage: multerS3({
s3: s3,
bucket: 'some-bucket',
metadata: function (req, file, cb) {
cb(null, {fieldName: file.fieldname});
},
key: function (req, file, cb) {
cb(null, Date.now().toString())
}
})
})
MulterS3 Docs
回答4:
/*** Using Multer To Upload Image image is uploading */
const fileStorage = multer.diskStorage({
destination: function(req, file, cb) {
cb(null, "./public/uploads");
},
filename: function(req, file, cb) {
cb(null, file.originalname);
}
});
/** AWS catalog */
aws.config.update({
secretAccessKey: process.env.SECRET_KEY,
accessKeyId: process.env.ACCESS_KEY,
region: "us-east-1"
});
const s3 = new aws.S3();
const awsStorage = multerS3({
s3: s3,
bucket: process.env.BUCKET_NAME,
key: function(req, file, cb) {
console.log(file);
cb(null, file.originalname);
}
});
const upload = multer({
/**if you are using local storage than use
* storage: fileStorage,
* if you are using aws storage than use
* storage: awsStorage,
*/
storage: awsStorage,
limits: { fileSize: 5000000 },
fileFilter: function(req, file, cb) {
checkFileType(file, cb);
}
});
app.post("/user-profile-image", upload.single("profile"), (req, res, err) => {
try {
res.send(req.file);
} catch (err) {
res.send(400);
}
});
const checkFileType = (file, cb) => {
const filetypes = /jpeg|jpg|png|gif/;
const extname = filetypes.test(path.extname(file.originalname).toLowerCase());
const mimetype = filetypes.test(file.mimetype);
if (mimetype && extname) {
return cb(null, true);
} else {
cb("Error: Images Only!");
}
};
来源:https://stackoverflow.com/questions/40494050/uploading-image-to-amazon-s3-using-multer-s3-nodejs