Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Simple file upload to S3 using aws-sdk and Node/Express

I am at a loss of what I am doing wrong, here is what I have:

HTML

<html> <body>     <form method="POST" action="/upload" enctype="multipart/form-data">         <div class="field">             <label for="image">Image Upload</label>             <input type="file" name="image" id="image">         </div>         <input type="submit" class="btn" value="Save">     </form> </body> </html> 

Port 5000 is my Node.js server's port.

In this example I am using POST to /upload, and it works fine.

module.exports = function(app, models) {      var fs = require('fs');     var AWS = require('aws-sdk');     var accessKeyId =  process.env.AWS_ACCESS_KEY || "xxxxxx";     var secretAccessKey = process.env.AWS_SECRET_KEY || "+xxxxxx+B+xxxxxxx";      AWS.config.update({         accessKeyId: accessKeyId,         secretAccessKey: secretAccessKey     });      var s3 = new AWS.S3();      app.post('/upload', function(req, res){          var params = {             Bucket: 'makersquest',             Key: 'myKey1234.png',             Body: "Hello"         };          s3.putObject(params, function (perr, pres) {             if (perr) {                 console.log("Error uploading data: ", perr);             } else {                 console.log("Successfully uploaded data to myBucket/myKey");             }         });     });  } 

Now I want to post the file that I am POSTing, which is where the problem arises.

module.exports = function(app, models) {      var fs = require('fs');     var AWS = require('aws-sdk');     var accessKeyId =  process.env.AWS_ACCESS_KEY || "xxxxxx";     var secretAccessKey = process.env.AWS_SECRET_KEY || "+xxxxxx+B+xxxxxxx";      AWS.config.update({         accessKeyId: accessKeyId,         secretAccessKey: secretAccessKey     });      var s3 = new AWS.S3();      app.post('/upload', function(req, res){         var path = req.files.image.path;         fs.readFile(path, function(err, file_buffer){             var params = {                 Bucket: 'makersquest',                 Key: 'myKey1234.png',                 Body: file_buffer             };              s3.putObject(params, function (perr, pres) {                 if (perr) {                     console.log("Error uploading data: ", perr);                 } else {                     console.log("Successfully uploaded data to myBucket/myKey");                 }             });         });     }); } 

The error I get is:

TypeError: Cannot read property 'path' of undefined

As a matter of fact files is completely empty.

I am assuming I am missing something pretty obvious but I can't seem to find it.

like image 240
abritez Avatar asked Jul 29 '13 17:07

abritez


People also ask

What is the recommended way to upload a single large file to an S3 bucket?

Short description. When you upload large files to Amazon S3, it's a best practice to leverage multipart uploads. If you're using the AWS Command Line Interface (AWS CLI), then all high-level aws s3 commands automatically perform a multipart upload when the object is large.


1 Answers

You will need something like multer to handle multipart uploading. Here is an example streaming your file upload to s3 using aws-sdk.

var multer = require('multer'); var AWS = require('aws-sdk');  var accessKeyId =  process.env.AWS_ACCESS_KEY || "xxxxxx"; var secretAccessKey = process.env.AWS_SECRET_KEY || "+xxxxxx+B+xxxxxxx";  AWS.config.update({     accessKeyId: accessKeyId,     secretAccessKey: secretAccessKey });  var s3 = new AWS.S3();  app.use(multer({ // https://github.com/expressjs/multer   dest: './public/uploads/',    limits : { fileSize:100000 },   rename: function (fieldname, filename) {     return filename.replace(/\W+/g, '-').toLowerCase();   },   onFileUploadData: function (file, data, req, res) {     // file : { fieldname, originalname, name, encoding, mimetype, path, extension, size, truncated, buffer }     var params = {       Bucket: 'makersquest',       Key: file.name,       Body: data     };      s3.putObject(params, function (perr, pres) {       if (perr) {         console.log("Error uploading data: ", perr);       } else {         console.log("Successfully uploaded data to myBucket/myKey");       }     });   } }));  app.post('/upload', function(req, res){     if(req.files.image !== undefined){ // `image` is the field name from your form         res.redirect("/uploads"); // success     }else{         res.send("error, no file chosen");     } }); 
like image 59
theRemix Avatar answered Oct 11 '22 08:10

theRemix