AngularJs图片上传到S3

我是:
– 创build一个Web应用程序
– AngularJS前端与ngfile upload( https://github.com/danialfarid/ng-file-upload )
– Node.js后端
– 希望能够将图像上传到我的Amazon S3存储桶

我试图按照这个教程: https : //github.com/danialfarid/ng-file-upload/wiki/Direct-S3-upload-and-Node-signing-example

本质上,程序stream程是select文件,单击button,请求从后端签名,然后上传到S3。

我使用代码200从后端接收签名,但是当前端尝试上载图像时,我在开发人员菜单中看到了这一点:
OPTIONS https://mybucket.name.s3-us-east-1.amazonaws.com/ net::ERR_NAME_NOT_RESOLVED

是我的代码是问题还是我设置我的桶的方式?

根据需要添加代码:

我的S3桶上的CORS

 <?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. }); }; }]); 

这个例子包含了一些我认为是过分简化的错误。

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

这在很大程度上是有效的,但是它并不是在S3中构build一个对象的一个​​有效的方法。

它至less打破了两个例子,其中之一就是你遇到的那个。

位于AWS的美国 东部地区的美国标准地区S3的终点不是s3-us-east-1.amazonaws.com ,因为如果它使用相同的格式其他地区。 看起来是遗传/进化的原因,它只是s3.amazonaws.com但也可以写成s3-external-1.amazonaws.com 。 (请记住,在写这篇文章的时候,S3已经有将近十年的时间了,服务已经扩展和发展了,同时保持了向后兼容性 – 这是一个值得注意的function,但一定会导致一些看起来容易混淆的约定。

然而,所有的桶(包括那些不在我们这里的东东),但是不包括那些因为第二个原因(我还没有得到)而破坏上述代码的bucket-name.s3.amazonaws.com可以简单地称为bucket-name.s3.amazonaws.com – 如果您考虑DNS的层次性,您可以看到这是如何工作的:S3,在创build桶之后的几分钟内,重新映射DNS中的特定主机名以发送请求到正确的区域S3端点。

所以+ '.s3-' + aws.region +应该可以工作,只要写成简单的+ '.s3' +

…除非你创造了一个名字上有点的桶。 在这种情况下,您将遇到https问题(这是问题#2,上面提到的问题),因为名称中带点的存储桶与S3提供的通配SSL(TLS)证书不匹配(SSL中的devise限制通配符证书,而不是S3本身)。

如果这是一个问题,并且由于某种原因使用名称中没有点的桶是不合需要的,那么您的URL必须以所谓的path样式格式制作。 这是虚拟样式格式的替代scheme,其中存储区名称位于主机名中。 这里,存储桶名称是path的第一部分:

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

…而且,对于美国标准(us-east-1),第一个组件只是s3s3-external-1 …但使用此格式要求您匹配区域,与上述不同,DNS处理请求路由…否则S3会抛出永久redirect错误。

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

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

这是很多信息,但希望有助于解释不仅需要做不同的事情,而且为什么。

您的前端机器无法通过域名服务parsing主机名。 最可能的问题是您使用了上传到的服务器的错误主机名:

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

如果正在使用的主机名是正确的,请确认您尝试访问的主机的DNS信息可以从客户端获得。 例如,使用Linux下的dig命令或Windows下的nslookup。