为了获得一些乐趣并了解有关JS和新HTML5规范的更多信息,我决定构建一个文件上传器插件供我个人使用。
在我选择文件后,我将文件发送给我的Web Worker,将其拼接成1mb块并单独上传到我的服务器。我选择单独发送它们以获得个别进度回调和暂停/恢复功能(稍后)。
我遇到的问题是当我选择要上传的大量文件时。如果我只选择8,没问题。如果我选择99,服务器会在关于第20个文件后拒绝/中止,但有时候,它可能会在22,31,18之后停止 - 真正随机。
在中止之前,Firefox可以使用Chrome而不是Chrome。 Chrome称他们失败了#39;和Firefox称他们“流产”#39; Firefox通常会在关于文件40之后中止文件。不仅如此,我的测试服务器也没有响应,并且会重置连接“#39;错误 - 在不到20秒后再次响应。
因为我正在使用Web Worker,所以我将我的XmlHttpRequests设置为同步以允许每个请求在开始新请求之前完成且PHP脚本位于同一个域中,所以我感到很困惑看到请求被拒绝,并希望听到我的代码导致这种情况发生的问题。
这是发送给Worker的插件部分。相当无关,但谁知道:
var worker = new Worker('assets/js/uplift/workers/uplift-worker.js');
worker.onmessage = function(e) {
console.log(e.data);
};
worker.postMessage({'files':filesArr});
这是uplift-worker.js:
var files = [], p = true;
function upload(chunk) {
var upliftRequest = new XMLHttpRequest();
upliftRequest.onreadystatechange = function() {
if (upliftRequest.readyState == 4 && upliftRequest.status == 200) {
// do something
}
};
upliftRequest.setRequestHeader("Cache-Control", "no-cache");
upliftRequest.setRequestHeader("X-Requested-With", "XMLHttpRequest");
upliftRequest.open('POST', '../php/uplift.php', false);
upliftRequest.send(chunk);
}
function processFiles() {
for (var j = 0; j < files.length; j++) {
var blob = files[j];
const BYTES_PER_CHUNK = 1024 * 1024; // 1mb chunk sizes.
const SIZE = blob.size;
var start = 0,
end = BYTES_PER_CHUNK;
while (start < SIZE) {
var chunk = blob.slice(start, end);
upload(chunk);
start = end;
end = start + BYTES_PER_CHUNK;
}
p = j == (files.length -1);
self.postMessage(blob.name + " uploaded successfully");
}
}
self.addEventListener('message', function(e) {
var data__Files = e.data.files;
for (var j = 0; j < data__Files.length; j++) {
files.push(data__Files[j]);
}
if (p) processFiles();
});
BUGS FOUND:
我设法从Chrome控制台获取此内容:
错误:第27行 http://xxxxxxx/demos/uplift/assets/js/uplift/workers/uplift-worker.js :Uncaught NetworkError:无法执行&#39;发送&#39;上 &#39; XMLHttpRequest&#39;:无法加载 &#39; http://xxxxxxx/demos/uplift/assets/js/uplift/php/uplift.php&#39;
指向工作人员脚本行:upliftRequest.send(chunk);
。
Firebug根本没有给我很多工作,但这显示了流产的请求:
这显示了随请求发送的标头:
我最初认为这是服务器端的问题,所以我从uplift.php
删除了所有PHP,并留下一个空白页面,只是测试上传到浏览器的部分并发布请求,但问题仍在继续。
更新
我开始认为我的托管服务提供商通过使用Apache Mod安全规则来限制请求率 - 可能是为了防止我的IP用暴力攻击服务器。除此之外,我的上传器在我的localhost(MAMP)上工作正常。
我对我的新怀疑做了一些研究。如果我的自制上传插件在向我的主机发送多个文件/请求时遇到了麻烦,那么肯定会有一些其他流行的上传插件可用,使用相同的技术并将文件发布到同一主机,也会在网上发布类似的投诉。这产生了一些好的结果,许多人支持我所拥有的经验。一个人上传了很多图片&#39;使用Uploadify HTML5(也发送个别请求)到同一主机,他的请求也被阻止。我想我最好联系他们,看看他们的限价是什么。
答案 0 :(得分:0)
我认为这是一个服务器端问题,即使使用普通的php文件..服务器将为每个请求打开一个新线程。在控制台中使用top
进行检查。
您正在while循环中上传块,而不必等到上一个块上传完成..
我会创建一个包含所有块的数组并执行upload(chunks)
并管理那里的并发,onreadystatechange
是一个很好的地方可以使用数组中的下一个块..