使用 multer-s3 nodejs 将图像上传到亚马逊 s3
Posted
技术标签:
【中文标题】使用 multer-s3 nodejs 将图像上传到亚马逊 s3【英文标题】:Uploading image to amazon s3 using multer-s3 nodejs 【发布时间】:2017-03-22 12:01:03 【问题描述】:我正在尝试使用 multer-s3
将图像上传到 amazon s3,但出现此错误:
TypeError:预期 opts.s3 为对象 node_modules/multer-s3/index.js:69:20
这是我的服务器代码:
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!");
);
为什么会出现这个错误?
【问题讨论】:
【参考方案1】: //here is the function for upload the images on aws bucket using multer
const path = require('path');
const fs = require('fs');
const aws = require('aws-sdk');
const multer = require('multer');
const multerS3 = require('multer-s3');
aws.config.update(
secretAccessKey: '**************************',
accessKeyId: '********************',
region: '**********************'
);
s3 = new aws.S3();
const storage = multerS3(
s3: s3,
bucket: 'bucket-name',
key: function(req, file, cb)
console.log(file);
cb(null, file.originalname);
)
//export the created function
exports.uploadVideo = multer( storage: storage ).single('file_name');
//================================================================================
//import uploadVideo function whenever you need to upload the file on aws s3 bucket
const uploadVideo = require('../../services/upload');
exports.videoUpload = (req, res) =>
uploadVideo(req, res, function(err)
if (err)
console.log(err);
res.json( status: 401, msg: err.message );
else
const image = getImagePath(req.file.filename);
res.json( status: 200, msg: 'Image uploaded sucess.', data: image );
);
//================================================================================
//here is route file
router.post('/video-upload',uploadController.videoUpload);
【讨论】:
【参考方案2】:我只想加分,
上传后如何获取公共 URL 和 S3 响应对象等所有答案中都有很多 cmets,让我们看看实现和案例,
// INITIALIZE NPMS
var AWS = require('aws-sdk'),
multer = require('multer'),
multerS3 = require('multer-s3'),
path = require('path');
// CONFIGURATION OF S3
AWS.config.update(
secretAccessKey: '***********************************',
accessKeyId: '****************',
region: 'us-east-1'
);
// CREATE OBJECT FOR S3
const S3 = new AWS.S3();
// CREATE MULTER FUNCTION FOR UPLOAD
var upload = multer(
// CREATE MULTER-S3 FUNCTION FOR STORAGE
storage: multerS3(
s3: S3,
acl: 'public-read',
// bucket - WE CAN PASS SUB FOLDER NAME ALSO LIKE 'bucket-name/sub-folder1'
bucket: 'bucket-name',
// META DATA FOR PUTTING FIELD NAME
metadata: function (req, file, cb)
cb(null, fieldName: file.fieldname );
,
// SET / MODIFY ORIGINAL FILE NAME
key: function (req, file, cb)
cb(null, file.originalname); //set unique file name if you wise using Date.toISOString()
// EXAMPLE 1
// cb(null, Date.now() + '-' + file.originalname);
// EXAMPLE 2
// cb(null, new Date().toISOString() + '-' + file.originalname);
),
// SET DEFAULT FILE SIZE UPLOAD LIMIT
limits: fileSize: 1024 * 1024 * 50 , // 50MB
// FILTER OPTIONS LIKE VALIDATING FILE EXTENSION
fileFilter: function(req, file, cb)
const filetypes = /jpeg|jpg|png/;
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: Allow images only of extensions jpeg|jpg|png !");
);
分三种情况,如果我们想上传后从S3中获取文件res
对象:
案例1:当我们使用.single(fieldname)
方法时,它会在req.file
app.post('/upload', upload.single('file'), function (req, res, next)
console.log('Uploaded!');
res.send(req.file);
);
案例 2: 当我们使用 .array(fieldname[, maxCount])
方法时,它会在 req.files
app.post('/upload', upload.array('file', 1), function (req, res, next)
console.log('Uploaded!');
res.send(req.files);
);
案例 3: 当我们使用 .fields(fields)
方法时,它会在 req.files
app.post('/upload', upload.fields([
name: 'avatar', maxCount: 1 ,
name: 'gallery', maxCount: 8
]), function (req, res, next)
console.log('Uploaded!');
res.send(req.files);
);
【讨论】:
您好,您能在这里看看我的问题吗,非常感谢您的帮助。***.com/questions/65479245/nodejs-multer-aws-s3 文件 URL 将在 req.file.location【参考方案3】:我正在将 S3 传递给大写字母 mutler,比如
S3: object
将其更改为小型 s3 对我有用:-
s3: object
【讨论】:
【参考方案4】:/*** Using Multer To Upload Image 图片正在上传 */
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(
storage: awsStorage(),
/** in above line if you are using local storage in ./public/uploads folder than use
******* storage: fileStorage,
* if you are using aws s3 bucket storage than use
******* 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!");
;
【讨论】:
欢迎来到 SO :) 请编辑您的答案以解释您的代码如何解决 OP 面临的问题。【参考方案5】:@V31 回答得很好,我还想加我的 2 美分。
我相信将一项职责保存到一个文件中,以实现更好的代码组织和调试目的。
我创建了一个文件用于上传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;
在我的路由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
帖子正文的邮递员屏幕截图
【讨论】:
能否请您发布必须从 Angular 前端或邮递员客户端调用的请求和正文的详细信息? @Satyam 请查看 Postman 中帖子正文的附件截图 下一个编辑可能是 :) @Anjum.... 回答得很好,但我想加我的 2 美分。【参考方案6】:完成并可以使用Node Cheat | Upload to s3 using multer-s3。
代码:
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!');
);
完整的回购:
克隆节点作弊express_multer_s3,运行node app
,然后运行npm install express body-parser aws-sdk multer multer-s3
。
乐于助人!
【讨论】:
为什么这个答案没有一百万个赞?这对我有帮助。谢谢。您可能需要更新:aws.config.update( signatureVersion: 'v4',
,因为我遇到了一个错误并且这样做解决了它。
真的很有帮助。
对我来说,同一行代码显示此错误"error":"errno":-4058,"syscall":"open","code":"ENOENT","path":"undefined/undefined"
我们如何获取上传文件的 s3 url。
我尝试了这段代码,我得到了一个类似“错误:多部分数据意外结束”的错误,我不知道为什么我这几天一直在寻找解决方案,请帮助我【参考方案7】:
s3
需要是要传递的对象。根据文档,对象需要是这样的:
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
【讨论】:
上面的accesskeyId在哪里提供 @mBlaze:您需要使用 aws sdk 使用 var s3 = new aws.S3( /* ... */ ) 创建一个 s3 对象。您可以使用链接docs.aws.amazon.com/sdk-for-javascript/v2/developer-guide/… 找到更多信息 @mBlaze:只是想知道您是否能够解决您的问题。如果是,请将答案标记为已接受。以上是关于使用 multer-s3 nodejs 将图像上传到亚马逊 s3的主要内容,如果未能解决你的问题,请参考以下文章
使用 multer 和 nodejs 将图像上传到谷歌云存储时出错
使用 Nodejs、Express、Mongoose 和 React 将图像上传到 MongoDB