【发布时间】:2018-12-01 13:16:20
【问题描述】:
我正在尝试使用 XMLHttpRequest 并行上传许多(目前为 3 个)文件。如果有一些代码可以从许多已删除文件的列表中提取它们,并确保我每时每刻都发送 3 个文件(如果可用)。
这是我的代码,据我所知是标准的:
var xhr = item._xhr = new XMLHttpRequest();
var form = new FormData();
var that = this;
angular.forEach(item.formData, function(obj) {
angular.forEach(obj, function(value, key) {
form.append(key, value);
});
});
form.append(item.alias, item._file, item.file.name);
xhr.upload.onprogress = function(event) {
// ...
};
xhr.onload = function() {
// ...
};
xhr.onerror = function() {
// ...
};
xhr.onabort = function() {
// ...
};
xhr.open(item.method, item.url, true);
xhr.withCredentials = item.withCredentials;
angular.forEach(item.headers, function(value, name) {
xhr.setRequestHeader(name, value);
});
xhr.send(form);
查看 Opera 开发者工具中的网络监视器,我发现这有点工作,并且我总是得到 3 个“正在进行中”的文件:
但是,如果我查看请求的进展方式,我会发现 3 个上传中的 2 个(这里是看似长时间运行的)处于“待处理”状态,并且 3 个请求中只有 1 个是真正的一次活跃。这也反映在上传时间中,因为这种并行性似乎没有发生时间改进。
我已经在我的代码中放置了控制台日志,看起来这不是我的代码的问题。
我应该知道的并行上传文件是否有任何浏览器限制?据我所知,AJAX 限制的请求数量比我在这里使用的要高得多......向请求中添加文件会改变事情吗?
【问题讨论】:
-
似乎是服务器端的错误。浏览器端没有问题。浏览器已经为 3 个请求同时请求握手。您的服务器一次可能只能处理 1 个请求。这就是握手长时间处于待处理状态的原因。您需要增加服务器能够处理的请求数。
-
@yeshashah 我的服务器是 ISS 并且没有设置限制。我的框架是 ASP.NET,在我的代码中没有任何地方可以锁定/阻止事物。 但是,在您发表评论并经过一番搜索后,我偶然发现了这一点,很可能是这种情况:stackoverflow.com/a/9016375/2173353。如果这是真的,我将不得不想办法绕过这种行为......
-
是的。许多服务器避免同时处理具有相同 sessionId 的请求,以避免写操作时出现竞争条件。 AWS S3 允许直接浏览器上传,其中文件被分成单独的块,每个块同时发送到服务器,然后服务器从 fileId 和 chunkId 以正确的顺序组装它们。你探索类似的东西。
-
@yeshashah 但是使用块有什么帮助呢?这最终不会有同样的问题吗?同样,这将是多个请求争夺同一个资源(在我的例子中是用户 Session 对象)。当然锁定时间会更小,但这些锁定时间的总和仍将与用于完整文件上传的时间相同(或多或少)。我很惊讶这会缩短上传时间。
-
我为 ASP 服务器找到的一个解决方案是禁用会话状态:stackoverflow.com/a/4319204/2873331
Setting EnableSessionState="ReadOnly" will prevent that page from gaining an exclusive lock on the SessionState (but the page itself would have to wait for other non-ReadOnly requests by the user to finish before loading).不确定它的效果如何。
标签: javascript ajax browser asp.net-mvc-5 xmlhttprequest