4

我:
- 創建Web應用程序
- AngularJS前端與NG-文件上傳(https://github.com/danialfarid/ng-file-upload
- Node.js的後端
- 希望能夠上傳圖片到我的亞馬遜S3存儲
AngularJs圖片上傳到S3

我試圖遵循本教程: https://github.com/danialfarid/ng-file-upload/wiki/Direct-S3-upload-and-Node-signing-example

本質上的程序流程選擇文件,點擊一個按鈕,請求從後端簽名,然後上傳到S3。

我收到來自後端簽署代碼爲200,但在前端試圖上傳我看到這個開發商菜單圖像:
OPTIONS https://mybucket.name.s3-us-east-1.amazonaws.com/ net::ERR_NAME_NOT_RESOLVED

是我的代碼,這個問題還是我的方式設置我的桶?如果需要的話

添加的代碼:我的S3存儲

<?xml version="1.0" encoding="UTF-8"?> 
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/"> 
    <CORSRule> 
     <AllowedOrigin>*</AllowedOrigin> 
     <AllowedMethod>GET</AllowedMethod> 
     <MaxAgeSeconds>3000</MaxAgeSeconds> 
     <AllowedHeader>Authorization</AllowedHeader> 
    </CORSRule> 
    <CORSRule> 
     <AllowedOrigin>my.computers.IP.Address</AllowedOrigin> 
     <AllowedMethod>PUT</AllowedMethod> 
     <AllowedMethod>POST</AllowedMethod> 
     <AllowedMethod>DELETE</AllowedMethod> 
     <AllowedHeader>*</AllowedHeader> 
    </CORSRule> 
</CORSConfiguration> 

Node.js的後端代碼

app.post('/signing', function(req, res) { 
    var request = req.body; 
    var fileName = request.filename 

    var extension = fileName.substring(fileName.lastIndexOf('.')); 
    var today = new Date(); 
    var path = '/' + today.getFullYear() + '/' + today.getMonth() + '/' + today.getDate() + '/' + uuid.v4() + extension; 

    var readType = 'private'; 

    var expiration = moment().add(5, 'm').toDate(); //15 minutes 

    var s3Policy = { 
     'expiration': expiration, 
     'conditions': [{ 
       'bucket': aws.bucket 
      }, 
      ['starts-with', '$key', path], 
      { 
       'acl': readType 
      }, 
      { 
       'success_action_status': '201' 
      }, 
      ['starts-with', '$Content-Type', request.type], 
      ['content-length-range', 2048, 10485760], //min and max 
     ] 
    }; 

    var stringPolicy = JSON.stringify(s3Policy); 
    var base64Policy = new Buffer(stringPolicy, 'utf-8').toString('base64'); 

    // sign policy 
    var signature = crypto.createHmac('sha1', aws.secret) 
     .update(new Buffer(base64Policy, 'utf-8')).digest('base64'); 

    var credentials = { 
     url: s3Url, 
     fields: { 
      key: path, 
      AWSAccessKeyId: aws.key, 
      acl: readType, 
      policy: base64Policy, 
      signature: signature, 
      'Content-Type': request.type, 
      success_action_status: 201 
     } 
    }; 
    res.jsonp(credentials); 
}); 

AngularJS前端代碼

App.controller('MyCtrl2', ['$scope', '$http', 'Upload', '$timeout', function ($scope, $http, Upload, $timeout) { 
    $scope.uploadPic = function(file) { 
     var filename = file.name; 
     var type = file.type; 
     var query = { 
      filename: filename, 
      type: type 
     }; 
     $http.post('/signing', query) 
      .success(function(result) { 
       Upload.upload({ 
        url: result.url, //s3Url 
        transformRequest: function(data, headersGetter) { 
         var headers = headersGetter(); 
         delete headers.Authorization; 
         return data; 
        }, 
        fields: result.fields, //credentials 
        method: 'POST', 
        file: file 
       }).progress(function(evt) { 
        console.log('progress: ' + parseInt(100.0 * evt.loaded/evt.total)); 
       }).success(function(data, status, headers, config) { 
        // file is uploaded successfully 
        console.log('file ' + config.file.name + 'is uploaded successfully. Response: ' + data); 
       }).error(function() { 

       }); 
      }) 
      .error(function(data, status, headers, config) { 
       // called asynchronously if an error occurs 
       // or server returns response with an error status. 
     }); 
    }; 
}]); 
+0

請你能參加在這裏我的問題http://stackoverflow.com/questions/36549765/cant-find-my-uploaded-file-in-my-s3-bucket。你有沒有類似的問題? –

回答

1

該示例包含一些我認爲過分簡化的錯誤。

var s3Url = 'https://' + aws.bucket + '.s3-' + aws.region + '.amazonaws.com'; 

這工作多的時間,但它不是制定一個URL在S3對象的一貫有效途徑。

至少有兩種情況,其中一種是您遇到的情況。

爲S3的美國標準區域,它位於AWS的美國東1區,終點是不是s3-us-east-1.amazonaws.com,因爲這將是如果使用相同的格式,對於其他地區。看起來是遺傳/進化的原因,它只是s3.amazonaws.com,但也可以寫成s3-external-1.amazonaws.com。 (請記住,在撰寫本文時,S3已經有將近十年的時間了,該服務已經擴展和發展,同時保持向後兼容性 - 一個值得注意的壯舉,但必然會導致一些看起來容易混淆的約定。)

然而,所有桶 - 包括那些沒有在美國東1 - 但不包括那些將打破第二個原因上面的代碼(我還沒有得到又) - 可以解決簡稱爲bucket-name.s3.amazonaws.com - 如果你想了解更多關於DNS的分層特性,你可以看到這是如何工作的:S3,創建桶後,在幾分鐘之內,重新映射一個特定的主機名,DNS中,將請求發送到正確的區域S3端點。

所以+ '.s3-' + aws.region +應該工作,如果寫的,簡單地說,+ '.s3' +

...除非,當然,你已經創建了一個桶在其名稱中的點。在這種情況下,https會出現問題(這是問題#2,由上面提到),因爲名稱中帶點的存儲桶不符合S3提供的通配SSL(TLS)證書(SSL中的設計限制通配符證書,而不是S3本身)。

如果這是一個問題,並且由於某種原因使用名稱中沒有點的桶是不合需要的,那麼您的URL必須用所謂的路徑樣式格式製作。這是虛擬樣式格式的替代方法,其中存儲區名稱位於主機名中。在這裏,鬥名稱是路徑的第一部分:

https://s3[-region].amazonaws.com/bucket.name.with.dots/key-path 

...並再次,第一部分是隻爲美國標準s3s3-external-1(美國東部-1)...但使用這種格式要求你匹配區域,不像上面那樣,DNS處理請求路由......否則S3會拋出永久重定向錯誤。

http://docs.aws.amazon.com/AmazonS3/latest/dev/VirtualHosting.html

http://docs.aws.amazon.com/general/latest/gr/rande.html#s3_region

這是很多信息,但不僅你需要做的有何不同,也說明爲什麼希望有用。

+0

先生,請你,請你能參加在這裏我的問題http://stackoverflow.com/questions/36549765/cant-find-my-uploaded-file-in-my-s3-bucket。它與此類似。 TQ –

1

你的前置式

CORS終端機失敗g通過域名服務解析主機名。最有可能的問題是,你使用了錯誤的主機名要上傳到服務器:

mybucket.name.s3-us-east-1.amazonaws.com

如果正在使用的主機名是否正確,請驗證您試圖訪問該主機的DNS信息可從您的客戶獲得。例如,使用Linux下的dig命令或Windows下的nslookup。

+0

在這種情況下,主機名稱不正確;由於主機名在美國東1區的S3中工作的方式不可能,所以它不同於其他所有地區。 –