Welcome toVigges Developer Community-Open, Learning,Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
661 views
in Technique[技术] by (71.8m points)

node.js - How to upload multiple files in nodejs to AWS S3 and save file url into database?

Hi i need to upload multiple images at a time on s3. Currently i am using express-fileupload to upload single image on AWS, and i want to use same approach to make it upload multiple files to s3 and update images array with urls on mongodb.

My schema property:

const ServiceSchema = new mongoose.Schema(
{
    photo: [
        {
            type: String,
            default: 'no-photo.jpg',
        },
    ],
});
module.exports = mongoose.model('Service', ServiceSchema);

My Controller:

// @desc        Upload photo for service
// @route       PUT /api/v1/services/:id/photo
// @access      Private
exports.servicePhotoUpload = asyncHandler(async (req, res, next) => {
const service = await Service.findById(req.params.id);

if (!service) {
    return next(new ErrorResponse(`Service not found with id of ${req.params.id}`, 404));
}

// Make sure user adding service is business owner
if (service.user.toString() !== req.user.id && req.user.role !== 'admin') {
    return next(
        new ErrorResponse(
            `User ${req.user.id} is not authorized to update this service to business ${service._id}`,
            401
        )
    );
}

// File Upload validation
if (!req.files) {
    return next(new ErrorResponse(`Please upload a file.`, 400));
}

const file = req.files.file;

// Make sure it is a valid image file
if (!file.mimetype.startsWith('image')) {
    return next(new ErrorResponse(`Please upload a valid image file.`, 400));
}

//Check File Size
if (file.size > process.env.MAX_FILE_UPLOAD) {
    return next(
        new ErrorResponse(
            `Please upload an image less then ${process.env.MAX_FILE_UPLOAD / 1024}KB in size.`,
            400
        )
    );
}

// Create custom filename
file.name = `service-uploads/servicePhoto_${service._id}${path.parse(file.name).ext}`;

uploadToS3({
    fileData: req.files.file.data,
    fileName: file.name,
})
    .then(async (result) => {
        console.log('Success Result: ', result);

        await Service.findByIdAndUpdate(service._id, { photo: result.Location });

        return res
            .status(200)
            .json({ success: true, message: 'Service photo added successfully', url:    result.Location });
    })
    .catch((err) => {
        console.log(err);
        return next(new ErrorResponse('Failed to upload file to S3', 500));
    });
  });

My Utility File to upload File to S3:

const AWS = require('aws-sdk');

const uploadToS3 = (options) => {
// Set the AWS Configuration
AWS.config.update({
    accessKeyId: process.env.AWS_S3_ACCESS_KEY,
    secretAccessKey: process.env.AWS_S3_SECRET_KEY,
    region: 'us-east-2',
});

// Create S3 service object
const s3 = new AWS.S3({ apiVersion: '2006-03-01' });

// Setting up S3 upload parameters
const params = {
    Bucket: 'toolbox-uploads',
    Key: options.fileName, // File name you want to save as in S3
    Body: options.fileData, //
};

// Return S3 uploading function as a promise so return url can be handled properly
return s3.upload(params).promise();
};

module.exports = uploadToS3;

My Router:

const express = require('express');
const {
 servicePhotoUpload
} = require('../controllers/service');

const Service = require('../models/Service');

router.route('/:id/photo').put(protect, authorize('publisher', 'business', 'admin'),  servicePhotoUpload);
 module.exports = router;

This above code is workng 100%.

I am bit confused as there were different approach and none worked for me from google and stack overflow and none of them is getting return url and saving into database.

I want to make separate utility file to upload multiple files to 3 same as i did for single files to use them anywhere. That file should return uploaded urls so i can update my database. I have tried multer-s3 but no solution works for me.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)
等待大神答复

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to Vigges Developer Community for programmer and developer-Open, Learning and Share
...