如何使用 aws-sdk 在 Angular2 中构建 S3 上传器并检索 S3 数据
How do I build an S3 uploader and retrieve S3 data in Angular2 with the aws-sdk
似乎每个人都可以解释如何将文件发送到 S3,但不幸的是,我还没有找到任何关于如何将 S3 中的数据存储回我的 Angular2 MEAN 堆栈应用程序的信息。我猜这意味着我缺少一些简单的东西。
目前,我可以上传到 S3,但我在几秒钟后取回了 js 对象,尽管我已经尝试订阅 bucket.upload,但我似乎没有采取任何措施来捕获 s3存储桶信息。
有人可以帮我看看我在这里可能遗漏了什么吗?
这就是我正在做的事情。
我的模板:
<div class="form-group" >
<input type="file" (change)="uploadToS3($event)" #input />
</div>
我的组件:
export class ProfileImgUploadComponent implements OnInit {
// This class and template is to upload img to S3 and assign to profile
@Input() profile: Profile;
pic_main_loc = '';
file: File;
items: any[] = [];
policy: String;
s3signature: String;
constructor(private router: Router, private awsService: AWSUploadService, private http: Http ) {}
ngOnInit() {
//console.log(this.profile.first_name)
}
uploadToS3(file: any){
require('aws-sdk/dist/aws-sdk');
var AWS = window.AWS;
var file = file.target.files[0];
AWS.config.credentials = new AWS.Credentials("myID", "MyPassword");
var bucket = new AWS.S3({params: {Bucket: 'pcvidistorage1'}});
var params = {Key: file.name, ContentType: file.type, Body: file, "x-amz-acl": "public-read"};
console.log(params);
bucket.upload(params, function (err, data)
{
console.log(file.name);
console.log(err, data);
console.log('i am here');
return data
});
}
//Map file on change
onChange(event) {
var files = event.srcElement.files;
this.file = files[0];
console.log(this.file);
}
经过一段时间的搜索和破解,这就是我的发现。
我用亚马逊凭证创建了一个 aconfig.json 文件,如下所示:
{ "accessKeyId": "*****YourAccessKey****", "secretAccessKey": "***YourSecretKey****" }
我将文件的上传移到了节点端,因为我确定在本地上传更有意义,创建上传对象,验证文件符合标准,然后上传到 s3。 Node (ExpressJS) 路由文件的内容类似于下面粘贴的文件。
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: 'myGreatBucket'}});
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...');
});
我的 ProfileInputComponent 现在有了这个上传方法
upload() {
console.log('this.createdProfile before upload');
console.log(this.createdProfile);
this.uploadFileService.makeFileRequest("http://localhost:3000/upload", this.createdProfile.profileId, this.filesToUpload)
.then(
(result) => {
this.imageUploaded = true;
this.uploadFile = result.obj.path;
},
(error) => {
console.log('We are in error');
console.error(error);
});
}
upload-file.service 中的 makeFileRequest 方法如下所示:
makeFileRequest(url: string, profileId, files: Array<File>) {
const token = localStorage.getItem('token') ? '?token=' + localStorage.getItem('token') : '';
console.log('profileId in upload service is: ');
console.log(profileId);
const profileParam = 'profileId=' + profileId;
return new Promise((resolve, reject) => {
var formData: any = new FormData();
var xhr = new XMLHttpRequest();
for(var i = 0; i < files.length; i++) {
formData.append("uploads[]", files[i], files[i].name);
}
xhr.onreadystatechange = function () {
if (xhr.readyState == 4) {
if (xhr.status == 200) {
console.log('xhr.status is 200');
resolve(JSON.parse(xhr.response));
} else {
console.log('xhr.status is NOT 200');
reject(xhr.response);
}
}
};
xhr.open("POST", url+token+'&'+profileParam, true);
xhr.send(formData);
});
}
所以此时,文件被上传到本地位置。现在我将再创建一个对上面提到的节点方法的服务调用。我知道这会起作用,因为节点方法是用这个服务创建的实际 JSON 对象测试的。
这花了我一段时间才终于开始工作,但是如果你设置下面的路由,更新 sampleFile JSON 以指向你系统上的一个真实文件并用 Postman 命中它,它会发布一个文件到您的 S3 帐户。
希望这对您有所帮助。很高兴回答关于这个的任何问题,因为我想我终于有了我的 s3 A Ha 时刻。
似乎每个人都可以解释如何将文件发送到 S3,但不幸的是,我还没有找到任何关于如何将 S3 中的数据存储回我的 Angular2 MEAN 堆栈应用程序的信息。我猜这意味着我缺少一些简单的东西。
目前,我可以上传到 S3,但我在几秒钟后取回了 js 对象,尽管我已经尝试订阅 bucket.upload,但我似乎没有采取任何措施来捕获 s3存储桶信息。
有人可以帮我看看我在这里可能遗漏了什么吗?
这就是我正在做的事情。
我的模板:
<div class="form-group" >
<input type="file" (change)="uploadToS3($event)" #input />
</div>
我的组件:
export class ProfileImgUploadComponent implements OnInit {
// This class and template is to upload img to S3 and assign to profile
@Input() profile: Profile;
pic_main_loc = '';
file: File;
items: any[] = [];
policy: String;
s3signature: String;
constructor(private router: Router, private awsService: AWSUploadService, private http: Http ) {}
ngOnInit() {
//console.log(this.profile.first_name)
}
uploadToS3(file: any){
require('aws-sdk/dist/aws-sdk');
var AWS = window.AWS;
var file = file.target.files[0];
AWS.config.credentials = new AWS.Credentials("myID", "MyPassword");
var bucket = new AWS.S3({params: {Bucket: 'pcvidistorage1'}});
var params = {Key: file.name, ContentType: file.type, Body: file, "x-amz-acl": "public-read"};
console.log(params);
bucket.upload(params, function (err, data)
{
console.log(file.name);
console.log(err, data);
console.log('i am here');
return data
});
}
//Map file on change
onChange(event) {
var files = event.srcElement.files;
this.file = files[0];
console.log(this.file);
}
经过一段时间的搜索和破解,这就是我的发现。
我用亚马逊凭证创建了一个 aconfig.json 文件,如下所示:
{ "accessKeyId": "*****YourAccessKey****", "secretAccessKey": "***YourSecretKey****" }
我将文件的上传移到了节点端,因为我确定在本地上传更有意义,创建上传对象,验证文件符合标准,然后上传到 s3。 Node (ExpressJS) 路由文件的内容类似于下面粘贴的文件。
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: 'myGreatBucket'}});
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...');
});
我的 ProfileInputComponent 现在有了这个上传方法
upload() {
console.log('this.createdProfile before upload');
console.log(this.createdProfile);
this.uploadFileService.makeFileRequest("http://localhost:3000/upload", this.createdProfile.profileId, this.filesToUpload)
.then(
(result) => {
this.imageUploaded = true;
this.uploadFile = result.obj.path;
},
(error) => {
console.log('We are in error');
console.error(error);
});
}
upload-file.service 中的 makeFileRequest 方法如下所示:
makeFileRequest(url: string, profileId, files: Array<File>) {
const token = localStorage.getItem('token') ? '?token=' + localStorage.getItem('token') : '';
console.log('profileId in upload service is: ');
console.log(profileId);
const profileParam = 'profileId=' + profileId;
return new Promise((resolve, reject) => {
var formData: any = new FormData();
var xhr = new XMLHttpRequest();
for(var i = 0; i < files.length; i++) {
formData.append("uploads[]", files[i], files[i].name);
}
xhr.onreadystatechange = function () {
if (xhr.readyState == 4) {
if (xhr.status == 200) {
console.log('xhr.status is 200');
resolve(JSON.parse(xhr.response));
} else {
console.log('xhr.status is NOT 200');
reject(xhr.response);
}
}
};
xhr.open("POST", url+token+'&'+profileParam, true);
xhr.send(formData);
});
}
所以此时,文件被上传到本地位置。现在我将再创建一个对上面提到的节点方法的服务调用。我知道这会起作用,因为节点方法是用这个服务创建的实际 JSON 对象测试的。
这花了我一段时间才终于开始工作,但是如果你设置下面的路由,更新 sampleFile JSON 以指向你系统上的一个真实文件并用 Postman 命中它,它会发布一个文件到您的 S3 帐户。
希望这对您有所帮助。很高兴回答关于这个的任何问题,因为我想我终于有了我的 s3 A Ha 时刻。