我正在寻找一个 HTML 5 AJAX 库/框架,供用户将文件直接上传到 Amazon S3。目标是避免将附件上传到网络服务器(因为网络服务器在将附件传输到亚马逊时会阻止)。我的理解是,使用 XDomainRequest 应该可以实现这一点,但我不知道如何实现。
我正在运行 ruby-on-rails,并希望为上传的文件分配一个临时名称(使用 UUID),该名称将被发布回 Web 服务器,以便稍后可以重命名该文件并与回形针集成。
有什么想法吗?这是 jQuery 可以处理的吗? Flash 不是该项目的选择。谢谢!
编辑:
我成功地完成了基本的工作,但仍然遇到问题。我不太确定需要哪些标头,或者如何在请求中对亚马逊所需的参数进行编码(我可以将它们放在请求标头中吗?)。这是迄今为止我的进展:
const XMLHTTPFactories = [
function () { return new XDomainRequest(); },
function () { return new XMLHttpRequest(); },
function () { return new ActiveXObject("Msxml2.XMLHTTP"); },
function () { return new ActiveXObject("Msxml3.XMLHTTP"); },
function () { return new ActiveXObject("Microsoft.XMLHTTP"); },
];
var xhr = null;
for (var i = 0; i < XMLHttpFactories.length; i++) {
try { xhr = XMLHttpFactories[i](); break; } catch (exception) { continue; }
}
$(this).change(function () {
for (var i = 0; i < this.files.length; i++) {
var file = this.files[i];
xhr.open(settings.method, settings.url, true);
xhr.setRequestHeader("Cache-Control", "no-cache");
xhr.setRequestHeader("Content-Type", "multipart/form-data");
xhr.setRequestHeader("Access-Control-Allow-Origin", "*")
xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest");
xhr.setRequestHeader("X-File-Name", file.fileName);
xhr.setRequestHeader("X-File-Size", file.fileSize);
xhr.send(file);
}
编辑:
进一步更新后,我设法收到以下错误:
XMLHttpRequest 无法加载
http://bucket.s3.amazonaws.com/。
来源 http://local.app 是
不允许
访问控制允许来源。
我上传了一个 crossdomain.xml
文件,该文件允许从通配符 (*) 域进行访问。不知道如何继续...
编辑:
在进行了更多调查后,我开始认为 JavaScript POST 可能无法用于 S3。在进行转移之前,我是否需要发布到 EC2 实例?我也许能够保护微型实例,但如果可能的话,我更愿意直接进入 S3!谢谢!
编辑:
我在亚马逊论坛上发布了该问题,但尚未收到任何反馈。对于交叉引用,可以在此处找到其他帖子:https://forums。 aws.amazon.com/message.jspa?messageID=206650#206650。
I am looking for an HTML 5 AJAX library / framework for users to upload files directly to Amazon S3. The goal is to avoid uploading attachments to the web server (as the web server blocks when it transfer them to Amazon). My understanding is that this should be possible using XDomainRequest
, but I can't figure out how.
I am running ruby-on-rails and wanted to assign the uploaded file a temporary name (using a UUID) that will be posted back to the web server so the file can later be renamed and integrated with paperclip.
Any ideas? Is this something jQuery can handle? Flash isn't an option for this project. Thanks!
Edit:
I managed to get a basic post working but am still have issues. I'm not exactly sure what headers are required, or how to encode the Amazon required parameters in the request (can I put them in the request header?). Here is my progress thus far:
const XMLHTTPFactories = [
function () { return new XDomainRequest(); },
function () { return new XMLHttpRequest(); },
function () { return new ActiveXObject("Msxml2.XMLHTTP"); },
function () { return new ActiveXObject("Msxml3.XMLHTTP"); },
function () { return new ActiveXObject("Microsoft.XMLHTTP"); },
];
var xhr = null;
for (var i = 0; i < XMLHttpFactories.length; i++) {
try { xhr = XMLHttpFactories[i](); break; } catch (exception) { continue; }
}
$(this).change(function () {
for (var i = 0; i < this.files.length; i++) {
var file = this.files[i];
xhr.open(settings.method, settings.url, true);
xhr.setRequestHeader("Cache-Control", "no-cache");
xhr.setRequestHeader("Content-Type", "multipart/form-data");
xhr.setRequestHeader("Access-Control-Allow-Origin", "*")
xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest");
xhr.setRequestHeader("X-File-Name", file.fileName);
xhr.setRequestHeader("X-File-Size", file.fileSize);
xhr.send(file);
}
Edit:
After further updates, I've managed to get the following error:
XMLHttpRequest cannot load
http://bucket.s3.amazonaws.com/.
Origin http://local.app is
not allowed by
Access-Control-Allow-Origin.
I've uploaded a crossdomain.xml
file that allows access from the wildcard (*) domain. Not sure how to continue...
Edit:
After having done more investigation, I'm starting to think that the JavaScript POST might not be possible to S3. Will I be required to post to an EC2 instance before doing a transfer? I might be able to secure a micro instance, but I'd prefer to go direct to S3 if possible! Thanks!
Edit:
I posted the question on the Amazon Forums and haven't received any feedback. For cross references the other post can be found here: https://forums.aws.amazon.com/message.jspa?messageID=206650#206650.
发布评论
评论(7)
您需要让对方发出
Access-Control-Allow-Origin
标头< /a>.在您的情况下,另一端是 Amazon S3 服务器。除非他们在该标头中提及您的域,否则您将无法向他们发出任何跨站点请求。Amazon S3 现在支持跨源资源共享< /a> 并且您可以通过向存储桶添加一个或多个 CORS 规则来配置任何 S3 存储桶以进行跨域访问。每条规则都可以指定一个有权访问您的存储桶的域以及您希望允许的一组 HTTP 动词。
You need to make the other side issue an
Access-Control-Allow-Origin
header. In you case the other side is Amazon S3 server. Unless they mention your domain in that header you won't be able to make any cross-site requests to them.Amazon S3 now supports Cross Origin Resource Sharing and you can configure any of your S3 buckets for cross-domain access by adding one or more CORS rules to your bucket. Each rule can specify a domain that should have access to your bucket and a set of HTTP verbs you wish to allow.
今天,Amazon 宣布在 Amazon S3 中完全支持跨域资源共享 (CORS)。您现在可以轻松构建使用 JavaScript 和 HTML5 与 Amazon S3 中的资源交互的 Web 应用程序,从而使您能够实现 HTML5 拖放上传到 Amazon S3、显示上传进度或更新内容。
Today Amazon announces complete support for Cross-Origin Resource Sharing (CORS) in Amazon S3. You can now easily build web applications that use JavaScript and HTML5 to interact with resources in Amazon S3, enabling you to implement HTML5 drag and drop uploads to Amazon S3, show upload progress, or update content.
这意味着您必须在 JavaScript 中公开您的 S3 凭证。你不想要这样。最好的解决方案是使用回形针。是的,您必须先上传到您的服务器,但至少它是安全的。没关系,检查评论。
This would mean that you have to expose your S3 credentials in JavaScript. You don't want that.The best solution is to use Paperclip. Yes, you must upload to your server first, but at least its secure.Nevermind that, check the comments.
S3 可以使用 jquery 托管 html 页面,没有问题。
该存储桶成为服务器 URL。
如果您使用 S3 Bucket Explorer 等工具,您可以一键获取存储桶中任何 HTML 页面的 URL。
然后您可以简单地使用 XMLHttpRequest 中的 PUT 命令来上传文件。
这本质上就是 JQuery-HTML5-Upload 插件在 Amazon S3 上的工作方式(请参阅问题 #12)。
事实上,您可以试验 Amazon S3 REST API 语法,只需将其插入变量中,然后将其与 XMLHttpRequest open() 方法结合使用。
多元宇宙的和平。
S3 can host html pages with jquery no problem.
The bucket becomes the server URL.
If you use a tool like S3 Bucket Explorer you can get a URL in one click for any HTML page in a bucket.
Then you can simply use the PUT command in an XMLHttpRequest to upload files.
This is essentially how the JQuery-HTML5-Upload plugin works for Amazon S3 (See their Issue #12).
In fact you can experiment with the Amazon S3 REST API syntax by just plugging it into variables and then using that in conjunction with the XMLHttpRequest open() method.
Peace in the multiverse.
亚马逊终于添加了对跨源资源共享(CORS)的支持,这允许这样做:
http ://aws.typepad.com/aws/2012/08/amazon-s3-cross-origin-resource-sharing.html
Amazon has finally added support for Cross Origin Resource Sharing (CORS) which allows this:
http://aws.typepad.com/aws/2012/08/amazon-s3-cross-origin-resource-sharing.html
我自己没有尝试过,但他们似乎在 jquery-html5-upload 插件中可以使用此功能
http://code.google.com/p/jquery-html5-upload/issues/detail?id=12
Have not tried myself, but they seem to have this working in the jquery-html5-upload plugin
http://code.google.com/p/jquery-html5-upload/issues/detail?id=12
有一个很好的 Rails gem,名为 s3_drect_upload ,它开箱即用,可以满足您的需求。它是一个 html5/javascript 上传器,支持重命名文件。
There is a good rails gem called s3_drect_upload which does exactly what you want out of the box. It's an html5/javascript uploader with support for renaming files.