2013-10-24 134 views
12

我正在尝试将文件上传到我的Amazon S3存储桶。 S3和亚马逊成立。 这是亚马逊的错误消息:如何使用Meteor将文件上传到Amazon S3?

冲突的查询字符串参数:ACL,策略

政策和签名进行编码,以Crypto.jsNode.js的

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

我想用流星HTTP.post方法来构建POST请求。这也可能是错误的。

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); 

这是我使用的是流星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); 
     } 
    }); 

和她我编码规则及其签名:

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"); 
} 

一个想不通了解正在发生的事情。 POST方法或加密可能已经存在问题,因为我不太了解这些方法。如果有人能指向我正确的方向,编码或正确发送POST请求到AmazonS3,它可能会有很大的帮助。
(我不喜欢用filepicker.io,因为我不想强迫客户签署了那里。)提前

谢谢!

+0

queryString is not与POST params一样,也许你需要在GET url上复制两个抱怨的参数... – dandavis

回答

5

直接上传到S3您可以使用slingshot包:

meteor add edgee:slingshot 

在服务器端声明你的指令:

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; 
    } 
}); 

该指令将自动生成策略和签名。

而且他们只需上传这样的:

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}}); 
}); 
+0

这是一个相当古老的问题,那里当时没有Slingshot包装。现在有了,而且还不错。直接从浏览器上传文件,所以我接受这个答案,而不是在服务器上运行的Hubert's。 感谢分享! – zalavari

4

为什么不使用aws-sdk包?它为您提供了所有需要的方法。例如,下面是简单的功能将文件添加到斗:

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

谢谢,这可能是如此明显。我甚至不知道我是如何错过这个软件包的。我走了试试看吧知道。 – zalavari

+0

我工作,谢谢。但仍然有问题,与上传的数据... – zalavari

+0

你发送正确吗?这可能有点棘手。如果你的配置有问题,最好打开一个新的问题,因为它有点不同的问题。 –

1

退房的S3流星包。自述文件有一个非常全面的演练如何开始

0

第一件事是添加s3文件上传的包。

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

1.创建指令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。获取Access密钥并将其粘贴到您的fileUpload.js文件中。

AWS.config.update({ 
accessKeyId: ' AKIAJ2TLJBEUO6IJLKMN ', 
secretAccessKey: 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' 
}); 

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

3.Now把这个上传的代码在你的指令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在“saveFile的”方法粘贴此代码

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

}; 

5.In HTML粘贴此代码

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