I am at a loss of what I am doing wrong, here is what I have:
我不知道我做错了什么,这就是我所拥有的:
HTML
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.
端口5000是我的Node.js服务器的端口。
In this example I am using POST
to /upload
, and it works fine.
在这个例子中我使用POST来/上传,它工作正常。
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 POST
ing, which is where the problem arises.
现在我想发布我正在POST的文件,这是问题出现的地方。
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
TypeError:无法读取未定义的属性“path”
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.
我假设我错过了一些非常明显的东西,但我似乎无法找到它。
7 个解决方案
#1
24
You will need something like multer
to handle multipart uploading. Here is an example streaming your file upload to s3 using aws-sdk
.
你需要像multer这样的东西来处理多部分上传。以下是使用aws-sdk将文件上传到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");
}
});
#2
19
Latest Answer @ Dec-2016 [New]
最新答案@ 2016年12月[新]
Use multer-s3 for multipart uploading to s3 without saving on local disk as:
使用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!');
});
Latest Answer @ Mar-2016 [Old-One]
最新答案@ Mar-2016 [Old-One]
Edited 1 use multer@1.1.0
and multer-s3@1.4.1
for following snippet:
编辑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!');
});
For complete running example clone express_multer_s3 repo and run node app
.
对于完整运行示例,克隆express_multer_s3 repo并运行节点应用程序。
#3
2
Sounds like you might not have the express bodyParser middleware setup. Can you post your entire server file (app.js, server.js, what have you)
听起来你可能没有明确的bodyParser中间件设置。你可以发布整个服务器文件(app.js,server.js,你有什么)
#4
1
Instead of multipart/form-data, you can try using image/png or whatever the correct mime type is.
您可以尝试使用image / png或任何正确的mime类型,而不是multipart / form-data。
#5
1
You need something like multer in your set of middleware to handle multipart/form-data
for you and populate req.files
. From the doco:
您需要在您的中间件集中使用multer来处理多部分/表单数据并填充req.files。来自doco:
var express = require('express')
var multer = require('multer')
var app = express()
app.use(multer({ dest: './uploads/'}))
Now req.files.image.path
should be populated in your app.post
function.
现在应该在app.post函数中填充req.files.image.path。
#6
0
It looks like your req.files.image is undefined. console.log out what req.files.image returns and see if you can go from there.
看起来你的req.files.image是未定义的。 console.log退出req.files.image返回的内容,看看你是否可以从那里开始。
#7
0
This stack overflow was the best answer I found explaining exactly how to get Node to S3 working.
这个堆栈溢出是我发现的最佳答案,解释了如何让Node工作到S3。
AWS Missing credentials when i try send something to my S3 Bucket (Node.js)
当我尝试向S3 Bucket(Node.js)发送内容时,AWS缺少凭据
This in addition to some more stuff I had to hack on to get it all working. In my situation I was using a MEAN stack application so my Node file I was working with was a route file.
除了一些我不得不破解的东西,让它全部工作。在我的情况下,我使用的是MEAN堆栈应用程序,因此我使用的Node文件是一个路由文件。
my aconfig.json file with the amazon credentials looks like this:
我的带有amazon凭据的aconfig.json文件如下所示:
{ "accessKeyId": "*****YourAccessKey****", "secretAccessKey": "***YourSecretKey****" }
The final contents of the route file look like the file pasted below.
路径文件的最终内容类似于下面粘贴的文件。
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...');
});
This took me a while to finally get working, but if you setup the route below, update the sampleFile JSON to point to a real file on your system and hit it with Postman it will publish a file to your S3 account.
这花了我一段时间才终于开始工作,但是如果您设置下面的路线,请更新sampleFile JSON以指向您系统上的真实文件,并使用Postman命中它,它会将文件发布到您的S3帐户。
Hope this helps
希望这可以帮助
#1
24
You will need something like multer
to handle multipart uploading. Here is an example streaming your file upload to s3 using aws-sdk
.
你需要像multer这样的东西来处理多部分上传。以下是使用aws-sdk将文件上传到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");
}
});
#2
19
Latest Answer @ Dec-2016 [New]
最新答案@ 2016年12月[新]
Use multer-s3 for multipart uploading to s3 without saving on local disk as:
使用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!');
});
Latest Answer @ Mar-2016 [Old-One]
最新答案@ Mar-2016 [Old-One]
Edited 1 use multer@1.1.0
and multer-s3@1.4.1
for following snippet:
编辑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!');
});
For complete running example clone express_multer_s3 repo and run node app
.
对于完整运行示例,克隆express_multer_s3 repo并运行节点应用程序。
#3
2
Sounds like you might not have the express bodyParser middleware setup. Can you post your entire server file (app.js, server.js, what have you)
听起来你可能没有明确的bodyParser中间件设置。你可以发布整个服务器文件(app.js,server.js,你有什么)
#4
1
Instead of multipart/form-data, you can try using image/png or whatever the correct mime type is.
您可以尝试使用image / png或任何正确的mime类型,而不是multipart / form-data。
#5
1
You need something like multer in your set of middleware to handle multipart/form-data
for you and populate req.files
. From the doco:
您需要在您的中间件集中使用multer来处理多部分/表单数据并填充req.files。来自doco:
var express = require('express')
var multer = require('multer')
var app = express()
app.use(multer({ dest: './uploads/'}))
Now req.files.image.path
should be populated in your app.post
function.
现在应该在app.post函数中填充req.files.image.path。
#6
0
It looks like your req.files.image is undefined. console.log out what req.files.image returns and see if you can go from there.
看起来你的req.files.image是未定义的。 console.log退出req.files.image返回的内容,看看你是否可以从那里开始。
#7
0
This stack overflow was the best answer I found explaining exactly how to get Node to S3 working.
这个堆栈溢出是我发现的最佳答案,解释了如何让Node工作到S3。
AWS Missing credentials when i try send something to my S3 Bucket (Node.js)
当我尝试向S3 Bucket(Node.js)发送内容时,AWS缺少凭据
This in addition to some more stuff I had to hack on to get it all working. In my situation I was using a MEAN stack application so my Node file I was working with was a route file.
除了一些我不得不破解的东西,让它全部工作。在我的情况下,我使用的是MEAN堆栈应用程序,因此我使用的Node文件是一个路由文件。
my aconfig.json file with the amazon credentials looks like this:
我的带有amazon凭据的aconfig.json文件如下所示:
{ "accessKeyId": "*****YourAccessKey****", "secretAccessKey": "***YourSecretKey****" }
The final contents of the route file look like the file pasted below.
路径文件的最终内容类似于下面粘贴的文件。
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...');
});
This took me a while to finally get working, but if you setup the route below, update the sampleFile JSON to point to a real file on your system and hit it with Postman it will publish a file to your S3 account.
这花了我一段时间才终于开始工作,但是如果您设置下面的路线,请更新sampleFile JSON以指向您系统上的真实文件,并使用Postman命中它,它会将文件发布到您的S3帐户。
Hope this helps
希望这可以帮助