react nodejs node listobjects aws node.js file-upload amazon-s3 aws-sdk multer-s3

node.js - nodejs - aws-sdk typescript



Carga simple de archivos a S3 usando aws-sdk y Node/Express (7)

Última respuesta @ Dic-2016 [Nuevo]

Utilice multer-s3 para la carga de multer-s3 partes en s3 sin guardar en el disco local como:

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''); }); //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!''); });

Última respuesta @ Mar-2016 [Old-One]

Editado 1 use [email protected] y [email protected] para el siguiente fragmento :

var express = require(''express''), bodyParser = require(''body-parser''), multer = require(''multer''), s3 = require(''multer-s3''); var app = express(); app.use(bodyParser.json()); var upload = multer({ storage: s3({ dirname: ''/'', bucket: ''bucket-name'', secretAccessKey: ''XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'', accessKeyId: ''XXXXXXXXXXXXXXX'', region: ''us-east-1'', filename: function (req, file, cb) { 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''); }); //use by upload form app.post(''/upload'', upload.array(''upl''), function (req, res, next) { res.send("Uploaded!"); }); app.listen(3000, function () { console.log(''Example app listening on port 3000!''); });

Para completar el ejemplo de ejecución, clone express_multer_s3 repo y ejecute la node app .

No entiendo lo que estoy haciendo mal, esto es lo que tengo:

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 es el puerto de mi servidor Node.js.

En este ejemplo, estoy usando POST to /upload , y funciona bien.

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"); } }); }); }

Ahora quiero publicar el archivo que estoy POST , que es donde surge el problema.

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"); } }); }); }); }

El error que recibo es:

TypeError: no se puede leer la propiedad ''path'' de undefined

Como cuestión de hecho, los files están completamente vacíos.

Estoy asumiendo que me estoy perdiendo algo bastante obvio, pero parece que no puedo encontrarlo.


En lugar de multipart / form-data, puede intentar usar image / png o cualquiera que sea el tipo de mime correcto.


Este desbordamiento de pila fue la mejor respuesta que encontré para explicar exactamente cómo hacer funcionar Node to S3.

AWS Faltan credenciales cuando intento enviar algo a mi S3 Bucket (Node.js)

Esto además de algunas cosas más que tuve que hackear para que todo funcione. En mi situación, estaba usando una aplicación de pila MEAN, por lo que mi archivo Node con el que estaba trabajando era un archivo de ruta.

mi archivo aconfig.json con las credenciales de Amazon se ve así:

{ "accessKeyId": "*****YourAccessKey****", "secretAccessKey": "***YourSecretKey****" }

El contenido final del archivo de ruta se parece al archivo pegado a continuación.

router.post(''/sendToS3'', function(req, res) { var fs = require(''fs''); var multer = require(''multer''); var AWS = require(''aws-sdk''); var path = require(''path''); var awsCredFile = path.join(__dirname, ''.'', ''aconfig.json''); console.log(''awsCredFile is''); console.log(awsCredFile); AWS.config.loadFromPath(awsCredFile); var s3 = new AWS.S3(); var photoBucket = new AWS.S3({params: {Bucket: ''myGreatBucketName''}}); var sampleFile = { "_id" : 345345, "fieldname" : "uploads[]", "originalname" : "IMG_1030.JPG", "encoding" : "7bit", "mimetype" : "image/jpeg", "destination" : "./public/images/uploads", "filename" : "31a66c51883595e74ab7ae5e66fb2ab8", "path" : "/images/uploads/31a66c51883595e74ab7ae5e66fb2ab8", "size" : 251556, "user" : "579fbe61adac4a8a73b6f508" }; var filePathToSend = path.join(__dirname, ''../public'', sampleFile.path); function uploadToS3(filepath, destFileName, callback) { photoBucket .upload({ ACL: ''public-read'', Body: fs.createReadStream(filepath), Key: destFileName.toString(), ContentType: ''application/octet-stream'' // force download if it''s accessed as a top location }) // http://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/S3/ManagedUpload.html#httpUploadProgress-event .on(''httpUploadProgress'', function(evt) { console.log(evt); }) // http://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/S3/ManagedUpload.html#send-property .send(callback); } multer({limits: {fileSize:10*1024*1024}}); console.log(''filePathToSend is ''); console.log(filePathToSend); uploadToS3(filePathToSend, sampleFile.filename, function (err, data) { if (err) { console.error(err); return res.status(500).send(''failed to upload to s3'').end(); } res.status(200) .send(''File uploaded to S3: '' + data.Location.replace(/</g, ''&lt;'') + ''<br/><img src="'' + data.Location.replace(/"/g, ''&quot;'') + ''"/>'') .end(); }); console.log(''uploading now...''); });

Esto me tomó un tiempo para finalmente trabajar, pero si configura la ruta a continuación, actualice sampleFile JSON para que apunte a un archivo real en su sistema y apúntelo con Postman, publicará un archivo en su cuenta S3.

Espero que esto ayude


Necesita algo como multer en su conjunto de middleware para manejar datos multipart/form-data y rellenar req.files . Del doco:

var express = require(''express'') var multer = require(''multer'') var app = express() app.use(multer({ dest: ''./uploads/''}))

Ahora, req.files.image.path debe completarse en la función app.post .


Necesitará algo como multer para manejar la carga de multer partes. Aquí hay un ejemplo que transmite la carga de su archivo a s3 usando 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"); } });


Parece que no tienes la configuración de middleware de bodyParser express. ¿Puedes publicar todo tu archivo de servidor (app.js, server.js, qué tienes)


Parece que tu archivo req.files no está definido. console.log indique lo que devuelve req.files.image y vea si puede ir desde allí.