使用multer-s3 nodejs将图像上传到amazon s3

mBl*_*aze 16 file-upload amazon-s3 node.js multer multer-s3

我正在尝试使用上传图像到亚马逊s3 multer-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!");
});
Run Code Online (Sandbox Code Playgroud)

为什么我收到此错误?

Zee*_*mon 49

完成并正在工作的Node Cheat | 使用multer-s3上传到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!');
});
Run Code Online (Sandbox Code Playgroud)

完整的回购:

克隆节点 - 作弊express_multer_s3,node app然后运行npm install express body-parser aws-sdk multer multer-s3.

快乐帮助!

  • 为什么这个答案没有一百万个赞?这对我有帮助。谢谢。您可能想要更新:`aws.config.update({ signatureVersion: 'v4',`,因为我遇到了一个错误,这样做解决了它。 (5认同)
  • 我们如何获取上传文件的 s3 url。 (4认同)

Anj*_*... 7

@ 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; 
Run Code Online (Sandbox Code Playgroud)

这是我的路线内导入的 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
Run Code Online (Sandbox Code Playgroud)

邮递员截屏的屏幕截图

在此处输入图片说明


V31*_*V31 6

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())
    }
  })
})
Run Code Online (Sandbox Code Playgroud)

MulterS3文件


tur*_*hal 6

我只想加上我的美分,

在所有答案中都有很多评论,例如上传后如何获取公共 URLS3 响应对象,让我们看看实现和案例,

// 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();
Run Code Online (Sandbox Code Playgroud)
// 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 !");
        }
    }
});
Run Code Online (Sandbox Code Playgroud)

有三种情况,如果我们想在上传后从 S3检索文件res对象

案例 1:当我们使用.single(fieldname)方法时,它将返回文件对象req.file

app.post('/upload', upload.single('file'), function (req, res, next) {
    console.log('Uploaded!');
    res.send(req.file);
});
Run Code Online (Sandbox Code Playgroud)

情况 2:当我们使用.array(fieldname[, maxCount])方法时,它将返回文件对象req.files

app.post('/upload', upload.array('file', 1), function (req, res, next) {
    console.log('Uploaded!');
    res.send(req.files);
});
Run Code Online (Sandbox Code Playgroud)

情况 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);
});
Run Code Online (Sandbox Code Playgroud)