使用aws-sdk和Node / Express将简单的file upload到S3
我错过了我所做的一切,下面是我所拥有的:
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是我的Node.js服务器的端口。
在这个例子中,我正在使用POST
/upload
,而且工作正常。
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"); } }); }); }
现在我想发布我正在发布的文件,这是问题出现的地方。
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"); } }); }); }); }
我得到的错误是:
TypeError:无法读取未定义的属性“path”
事实上files
是完全空的。
我假设我失去了很明显的东西,但我似乎无法find它。
你需要像multer
一样处理多部分上传。 这是一个使用aws-sdk
将file upload到s3的例子。
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"); } });
最新回答@ Dec-2016 [新]
使用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'); }); //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!'); });
最新回答@ Mar-2016 [Old-One]
编辑1 使用 multer@1.1.0
和 multer-s3@1.4.1
以下摘录 :
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!'); });
对于完整的运行示例克隆express_multer_s3回购和运行node app
。
听起来你可能没有expressParser中间件设置。 你可以发布你的整个服务器文件(app.js,server.js,你有什么)
而不是multipart / form-data,你可以尝试使用image / png或任何正确的mimetypes。
您需要在中间件集合中使用诸如multer之类的东西来处理multipart/form-data
,并填充req.files
。 从doco:
var express = require('express') var multer = require('multer') var app = express() app.use(multer({ dest: './uploads/'}))
现在req.files.image.path
应该填充在你的app.post
函数中。
它看起来像你的req.files.image是未定义的。 console.log出req.files.image返回的内容,看看是否可以从那里出发。
这个堆栈溢出是我发现解释如何让Node到S3工作的最佳答案。
AWS尝试将消息发送给我的S3 Bucket(Node.js)
这除了一些我不得不破解的东西来完成所有的工作。 在我的情况下,我正在使用一个MEAN堆栈应用程序,所以我正在使用的节点文件是一个路由文件。
我的aconfig.json文件与亚马逊证书看起来像这样:
{ "accessKeyId": "*****YourAccessKey****", "secretAccessKey": "***YourSecretKey****" }
path文件的最终内容看起来像下面粘贴的文件。
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, '<') + '<br/><img src="' + data.Location.replace(/"/g, '"') + '"/>') .end(); }); console.log('uploading now...'); });
这花了我一些时间才能最终得到工作,但如果你设置下面的路线,更新sampleFile JSON指向您的系统上的一个真实的文件,并与邮递员打它将发布一个文件到您的S3帐户。
希望这可以帮助