Upload image to AWS S3 bucket using Node. JS
Asked Answered
S

2

7

I'm trying to upload an image to my S3 bucket from a webpage using node.js. I am able to create a folder, but uploading the image file to that folder is not working for me. Here are my dependencies in my package.json

"dependencies": {
    "aws-sdk": "^2.331.0",
    "bcrypt-nodejs": "0.0.3",
    "busboy": "^0.2.14",
    "busboy-body-parser": "^0.3.2",
    "connect-busboy": "0.0.2",
    "ejs": "^2.6.1",
    "express": "^4.16.3",
    "express-handlebars": "^3.0.0",
    "express-session": "^1.15.6",
    "mysql": "^2.16.0",
    "mysql2": "^1.6.1",
    "passport": "^0.4.0",
    "passport-local-sequelize": "^0.8.0",
    "path": "^0.12.7",
    "sequelize": "^4.39.0"
  }

and this is the part of my api_routes.js file that I'm working with

const bucketName = 'socialmemedia';
const bucketRegion = 'us-east-1';

AWS.config.update({
  region: bucketRegion
});
AWS.config.apiVersions = {
  s3: '2006-03-01',
};

const s3 = new AWS.S3();

module.exports = function (app) {
 // upload image to S3
  app.post("/api/upload", function (req, res) {
    const file = (req.body.imageUpload);
    const busboy = new Busboy({
      headers: req.headers
    });
    busboy.on('finish', function () {
      console.log('Upload finished');
      console.log(file);
      uploadToS3(file);
    });
     req.pipe(busboy);
  });


  function uploadToS3(file) {
    // console.log(req.body);

    const folder = (req.user.username + "/")
    console.log("Folder name: " + folder);
    const params = {
      Bucket: bucketName,
      Key: folder,
      ACL: 'public-read',
      Body: stream
    };

    s3.upload(params, function (err, data) {
      if (err) {
        console.log("Error: ", err);
      } else {
        console.log("Successfully created a folder on S3");
        
      }
    });
    res.redirect("/feed");
  }

};

and here is the form snippet

<form action="/api/upload" method="POST" class="image-form">
        <input id="image-upload" class="file-add" type="file" accept="image/*" name="imageUpload"/>
        <button type="submit" id="image-upload" class="sinsup-button">Upload Image</button>
</form>

any idea on how to get the image to actually upload into the S3 bucket?

Sonnier answered 13/10, 2018 at 16:17 Comment(0)
S
8

I figured it out, thanks for your help @me. I was using s3.upload instead of s3.putObject. Answering to help anyone else who may have this problem in the future.

  // upload image to S3
  app.post("/api/upload", function (req, res) {
    const folder = (req.user.username + "/");
    const file = (req.body.imageUpload);
    const params = {
      Bucket: bucketName,
      Key: (folder + file),
      ACL: 'public-read',
      Body: file
    };
    console.log("Folder name: " + folder);
    console.log("File: " + file);
    

    s3.putObject(params, function (err, data) {
      if (err) {
        console.log("Error: ", err);
      } else {
        console.log(data);
      }
    });
    res.redirect("/feed");
  });
Sonnier answered 13/10, 2018 at 17:14 Comment(2)
with putObject, i have use buffer and it only uploads first buffer, any idea?Lardy
not sure about why to use buffer if it's for image upload,if you can do the above with Key as file name and Body as actual file, remember we've to actually reference file properly to Body, Otherwise we can see file getting uploaded to S3 but will be having file format issues on downloading.Macrospore
E
0

simple answer would be to mention your folder name in your key s3 identifies it as a folder name and stores files in it

 const params = {
   Bucket: bucketName,
   Key: `${folder}/${file.filename}`, 
   Body: fileContent,
   ContentType: file.mimetype,
 };

 // Uploading files to the bucket
 s3.upload(params);
Essentialism answered 23/9, 2021 at 9:6 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.