直接(和简单!)AJAX从(AngularJS)单页应用程序上传到AWS S3
我知道上传到AWS S3有很多覆盖.不过,我一直在努力工作大概24个小时,而且还没有找到符合我情况的答案.
我想做什么 直接从我的客户端将文件上传到AWS S3到我的S3桶.情况是: >这是一个单页面应用程序,所以上传请求必须在AJAX中 我试过了 > Heroku’s article直接上传到S3.不符合我的客户端/服务器配置(加上它真的不适合和Angular) 看来我面临着两个困难:在我的单页应用程序中有一个文件输入,并获得AWS的工作流程. 我正在寻找的解决方案 如果可能的话,我想避免“全部包含”的解决方案来管理整个过程,同时隐藏所有的复杂性,使其很难适应特殊情况.我宁愿有一个简单的解释,分解所涉及的各个组件之间的数据流,即使它需要更多的管道从我.
我终于管理了要点是:
>放开Angular的$http,并使用本机XMLHttpRequest. 以下是我所做的一步一步的指导;它在服务器上使用AngularJS和NodeJS,但是应该很容易适应其他堆栈,特别是因为它处理最病态的情况(SPA在不同的域中,服务器,最近有一个桶)写作区域). 工作流汇总 >用户在浏览器中选择一个文件;您的JavaScript保持引用. 在你开始之前 确保: >您的服务器具有AWS SDK 步骤1:设置一个SPA友好的文件上传表单/小部件. 所有重要的是拥有一个工作流程,最终可以让您对File对象进行编程访问,而无需上传它. 在我的情况下,我使用了优秀的angular-file-upload库的ng-file-select和ng-file-drop指令.但是还有其他的方法(例如参见this post). 请注意,您可以访问文件对象中的有用信息,如file.name,file.type等. 步骤2:获取服务器上文件的签名URL 在您的服务器上,您可以使用AWS SDK获取一个安全的临时URL,从其他地方(如您的前端)将文件从PUT中删除. 在NodeJS中,我这样做: // --------------------------------- // some initial configuration var aws = require('aws-sdk'); aws.config.update({ accessKeyId: process.env.AWS_ACCESS_KEY,secretAccessKey: process.env.AWS_SECRET_KEY,signatureVersion: 'v4',region: 'eu-central-1' }); // --------------------------------- // now say you want fetch a URL for an object named `objectName` var s3 = new aws.S3(); var s3_params = { Bucket: MY_BUCKET_NAME,Key: objectName,Expires: 60,ACL: 'public-read' }; s3.getSignedUrl('putObject',s3_params,function (err,signedUrl) { // send signedUrl back to client // [...] }); 您可能想知道要获取对象的URL(通常是图像).为此,我只是从URL中删除查询字符串: var url = require('url'); // ... var parsedUrl = url.parse(signedUrl); parsedUrl.search = null; var objectUrl = url.format(parsedUrl); 步骤3:从客户端发送PUT请求 现在您的客户端具有您的File对象和已签名的URL,它可以将PUT请求发送到S3.在Angular案例中我的建议是使用XMLHttpRequest而不是$http服务: var signedUrl,file; // ... var d_completed = $q.defer(); // since I'm working with Angular,I use $q for asynchronous control flow,but it's not mandatory var xhr = new XMLHttpRequest(); xhr.file = file; // not necessary if you create scopes like this xhr.onreadystatechange = function(e) { if ( 4 == this.readyState ) { // done uploading! HURRAY! d_completed.resolve(true); } }; xhr.open('PUT',signedUrl,true); xhr.setRequestHeader("Content-Type","application/octet-stream"); xhr.send(file); 致谢 我要感谢emil10001和Will Webberley,他的出版物对我来说非常有价值. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |