6

我正在尝试使用 REST Api 和 HTML5 文件切片将一个大文件 (1.5GB) 上传到 Amazon S3。以下是上传代码的样子(为了便于阅读,代码被剥离):

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 开发工具中的外观:

在此处输入图像描述 在此处输入图像描述 在此处输入图像描述

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

编辑:这是OPTIONS回复:

在此处输入图像描述

4

2 回答 2

4

我终于通过嗅探数据包发现了问题:有两个问题:

  1. 对于PUT获得 a 的请求4xx(未测试其他非2xx响应),xhr 请求返回为 aborted (status = 0);仍然没有找到解释,请查看为什么 PUT 403 显示为已中止?

  2. Amazon S3 回复403RequestTimeTooSkewed,因为我的签名是在上传开始时生成的,并且在 15 分钟(触发RequestTimeTooSkewed错误的超时)后,它失败了,必须重新生成签名。由于第一个问题,在开发工具控制台或 js 代码中从未见过 403 错误。

重新生成签名后,一切都像魅力一样。

于 2012-09-28T08:18:23.290 回答
2

您是否验证浏览器是否正在发出任何“选项”请求。如果是,则响应标头是什么。

于 2012-09-27T23:41:25.333 回答