简体   繁体   English

如何使用Meteor将文件上传到Amazon S3?

[英]How to upload files to Amazon S3 with Meteor?

I'm trying to upload files to my Amazon S3 Bucket. 我正在尝试将文件上传到我的Amazon S3 Bucket。 S3 and amazon is set up. S3和亚马逊成立。 This is the error message from Amazon: 这是来自亚马逊的错误消息:

Conflicting query string parameters: acl, policy 冲突的查询字符串参数:acl,policy

Policy and signature is encoded, with Crypto.js for Node.js 使用Node.js的 Crypto.js对策略和签名进行编码

var crypto=Npm.require("crypto");

I'm trying to build POST request with Meteor HTTP.post method. 我正在尝试使用Meteor HTTP.post方法构建POST请求。 This could be wrong as well. 这也可能是错误的。

    var BucketName="mybucket";
    var AWSAccessKeyId="MY_ACCES_KEY";
    var AWSSecretKey="MY_SECRET_KEY";

    //create policy
    var POLICY_JSON={
        "expiration": "2009-01-01T00:00:00Z",
            "conditions": [ 
            {"bucket": BucketName}, 
            ["starts-with", "$key", "uploads/"],
            {"acl": 'public-read'},
            ["starts-with", "$Content-Type", ""],
            ["content-length-range", 0, 1048576],
        ]   
    }
    var policyBase64=encodePolicy(POLICY_JSON);
    //create signature
    var SIGNATURE = encodeSignature(policyBase64,AWSSecretKey);
    console.log('signature: ', SIGNATURE);

This is the POST request I'm using with Meteor: 这是我在Meteor上使用的POST请求:

    //Send data----------
    var options={
        "params":{
            "key":file.name,
            'AWSAccessKeyId':AWSAccessKeyId,
            'acl':'public-read',
            'policy':policyBase64,
            'signature':SIGNATURE,
            'Content-Type':file.type,
            'file':file,
            "enctype":"multipart/form-data",
        }
    }

    HTTP.call('POST','https://'+BucketName+'.s3.amazonaws.com/',options,function(error,result){
        if(error){
            console.log("and HTTP ERROR:",error);
        }else{
            console.log("result:",result);
        }
    });

and her I'm encoding the policy and the signature: 她正在对政策和签名进行编码:

encodePolicy=function(jsonPolicy){
    // stringify the policy, store it in a NodeJS Buffer object
    var buffer=new Buffer(JSON.stringify(jsonPolicy));
    // convert it to base64
    var policy=buffer.toString("base64");
    // replace "/" and "+" so that it is URL-safe.
    return policy.replace(/\//g,"_").replace(/\+/g,"-");
}

encodeSignature=function(policy,secret){
    var hmac=crypto.createHmac("sha256",secret);
    hmac.update(policy);
    return hmac.digest("hex");
}

A can't figure out whats going on. A无法弄清楚最近发生了什么。 There might already be a problem at the POST method, or the encryption, because I don't know these methods too well. POST方法或加密可能已经存在问题,因为我不太了解这些方法。 If someone could point me to the right direction, to encode, or send POST request to AmazonS3 properly, it could help a lot. 如果有人可以指出我正确的方向,编码或正确地向AmazonS3发送POST请求,它可能会有很大帮助。
(I don't like to use filepicker.io , because I don't want to force the client to sign up there as well.) (我不喜欢使用filepicker.io ,因为我不想强迫客户端在那里注册。)

Thanks in advance!!! 提前致谢!!!

Direct uploads to S3 you can use the slingshot package: 直接上传到S3你可以使用弹弓包:

meteor add edgee:slingshot

On the server side declare your directive: 在服务器端声明您的指令:

Slingshot.createDirective("myFileUploads", Slingshot.S3Storage, {
  bucket: "mybucket",
  allowedFileTypes: ["image/png", "image/jpeg", "image/gif"],

  acl: "public-read",

  authorize: function () {
    //You can add user restrictions here
    return true;
  },

  key: function (file) {
    return file.name;
  }
});

This directive will generate policy and signature automatically. 该指令将自动生成策略和签名。

And them just upload it like this: 他们只是像这样上传它:

var uploader = new Slingshot.Upload("myFileUploads");

uploader.send(document.getElementById('input').files[0], function (error, url) {
  Meteor.users.update(Meteor.userId(), {$push: {"profile.files": url}});
});

Why don't you use the aws-sdk package? 你为什么不使用aws-sdk包? It packs all the needed methods for you. 它包含了所有需要的方法。 For example, here's the simple function for adding a file to bucket: 例如,这是将文件添加到存储桶的简单功能:

s3.putObject({
  Bucket: ...,
  ACL: ...,
  Key: ...,
  Metadata: ...,
  ContentType: ...,
  Body: ...,
}, function(err, data) {
  ...
});

check out the S3 meteor package. 查看S3流星包。 The readme has a very comprehensive walkthrough of how to get started 自述文件有关如何入门的非常全面的演练

First thing is to add the package for s3 file upload. 首先是添加s3文件上传包。

For Installation: ADD (AWS SDK Smart Package) $ meteor add peerlibrary: aws-sdk 对于安装:ADD(AWS SDK智能包) $ meteor add peerlibrary: aws-sdk

1.Create Directive upload.js and paste this code. 1.创建Directive upload.js并粘贴此代码。

angular.module('techno')
.directive("fileupload", [function () {
    return {
        scope: {
            fileupload: "="
        },
        link: function(scope,element, attributes){
            $('.button-collapse').sideNav();
            element.bind("change", function (event) {
                scope.$apply(function () {
                 scope.fileupload = event.target.files[0];
             });
           })
       }};
}]);

2.Get Access key and paste it in your fileUpload.js file. 2.获取Access键并将其粘贴到fileUpload.js文件中。

AWS.config.update({
accessKeyId: ' AKIAJ2TLJBEUO6IJLKMN ',
secretAccessKey: lqGE9o4WkovRi0hCFPToG0B6w9Okg/hUfpVr6K6g'
});

AWS.config.region = 'us-east-1';
let bucket = new AWS.S3();

3.Now put this upload code in your directive fileUpload.js 3.现在将此上传代码放在指令fileUpload.js

vm.upload = (Obj) =>{
vm.loadingButton = true;
let name = Obj.name;
let params = {
    Bucket: 'technodheeraj',
    Key: name,
    ContentType: 'application/pdf',
    Body: Obj,
    ServerSideEncryption: 'AES256'
};

bucket.putObject(params, (err, data) => {
    if (err) {
        console.log('---err------->', err);
    }
    else {
        vm.fileObject = {
            userId: Meteor.userId(),
            eventId: id,
            fileName: name,
            fileSize: fileObj.size,
        };
   vm.call("saveFile", vm.fileObject, (error, result) => {
            if (!error){
                console.log('File saved successfully');

            }
        })
    }
})

};

4.Now in “saveFile” method paste this code 4.现在“saveFile”方法粘贴此代码

saveFile: function(file){
if(file){
    return Files.insert(file);
}

};

5.In HTML paste this code 5.在HTML中粘贴此代码

<input type="file" name="file" fileupload="file">
<button type="button" class="btn btn-info " ng-click="vm.upload(file)"> Upload File</button>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM