2012-09-27 101 views
6

我试图通过使用REST Api和HTML5文件切片将大文件(1.5GB)上传到Amazon S3。下面是上传代码的样子(剥离下来的可读性代码):Amazon S3 CORS PUT失败

File.prototype.slice = File.prototype.webkitSlice || File.prototype.mozSlice || File.prototype.slice; 

var length = u.settings.chunk_size; // 6MB 
var start = chunk * length; 
var end = Math.min(start + length, u.file.size); 

var xhr = new XMLHttpRequest(); 
var path = "/" + u.settings.key; 

path += "?partNumber=" + chunk + "&uploadId=" + u.upload_id; 

var method = "PUT"; 
var authorization = "AWS " + u.settings.access_key + ":" + signature; 
var blob = u.file.slice(start, end); 

xhr.upload.addEventListener("progress", progress_handler, true); 
xhr.addEventListener("readystatechange", handler, true); 
xhr.addEventListener("error", error_handler, true); 
xhr.addEventListener("timeout", error_handler, true); 

xhr.open(method, u.settings.host + path, true); 

xhr.setRequestHeader("x-amz-date", date); 
xhr.setRequestHeader("Authorization", authorization); 
xhr.setRequestHeader("Content-Type", u.settings.content_type); 
xhr.setRequestHeader("Content-Disposition", "attachment; filename=" + u.file.name); 

xhr.send(blob); 

chunk_size为6MB。在一个块完成上传之后,下一个将继续,依此类推。但有时(每80块左右),PUT请求失败,e.type == "error",e.target.status == 0(令我感到意外)和e.target.responseText == ""。块失败后,代码会重新尝试上传,并得到完全相同的错误。当我刷新页面并继续上传(同一块!)时,它就像一个魅力(80块左右,当它再次卡住)。这里的要求是如何看起来Chrome浏览器开发工具:

enter image description here enter image description here enter image description here

任何想法,为什么这件事会发生,或如何调试这样的事情?

编辑:这里是OPTIONS响应:

enter image description here

回答

4

我终于找到了问题的数据包嗅探:有两个问题:

  1. PUT要求将得到一个4xx(没有测试其它非2xx响应),在XHR请求返回的中止(状态= 0);仍然没有找到该解释,退房Why does a PUT 403 show up as Aborted?

  2. 亚马逊S3报以403提到RequestTimeTooSkewed,因为上传开始时我的签名生成,15分钟(即触发RequestTimeTooSkewed错误后超时),它会失败,签名必须重新生成。这403错误是从未见过的开发者工具控制台或JS代码,因为第一个问题的..

再生的签名之后,一切工作就像一个魅力。

+0

是的,理想情况下,您可以在发送请求的同时签署请求,而不是一开始就全部发送。 –

+0

@RyanParman是的,没错,但我的库在JS中,而且我需要在服务器端生成签名,而且我宁愿向服务器发出较少的请求。 –

+0

啊,知道了。是的,这有所作为。 :) –

2

你验证浏览器是否作出任何 'OPTIONS' 请求。如果是,什么是响应标题。

+0

查看我的编辑 –