2013-10-24 131 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>