如何使用 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, '&lt;')
            + '<br/><img src="' + data.Location.replace(/"/g, '&quot;') + '"/>')
        .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 时刻。