JavaScript:在完全发送文件后,降低异步XHR文件上传的超时值



通常,我总是在stackoverflow上找到解决问题的解决方案,你们真的很棒!但是经过数小时的搜索,我仍然遇到这个问题:

我正在编程Chrome/ff的浏览器扩展程序,该扩展程序通过XHR Post方法将文件上传到服务器。如果服务器不响应,我想给用户一个连接时间的反馈。因此,首先,我使用了10000毫秒的超时值,因为我认为超时仅在发送请求/文件后才开始计数。但是,事实证明,在慢速连接下,上传花费了10秒以上,并且超时事件在完全发送文件之前就触发了。对于一些较大的文件,上传甚至花了几分钟,因此我必须将超时值设置为5分钟。但是,这在快速连接上是不可行的。在快速连接上,我不想等待5分钟,然后才能通知用户,如果服务器未响应,则连接已计时。

因此,我正在寻找一个应该:

的XHR解决方案
  1. 首先将超时设置为例如文件上传过程中的5分钟,以允许在慢速连接上完全发送文件
  2. 将超时设置为例如如果服务器在收到整个文件后的10秒内未响应,则完全发送文件后10秒以超时连接。

有可能实现这一目标吗?

编辑:到目前为止我尝试的是:

[...]
var originalTimeout = 10000;
xhr.timeout = originalTimeout;
[...]
xhr.upload.addEventListener('loadstart', function(e) {
    xhr.timeout = 600000;
});
xhr.upload.addEventListener('loadend', function(e) {
    xhr.timeout = originalTimeout;
});

我进行了几次上传测试,很明显,Upload-'LoadStart'事件侦听器将超时值更改为600000,因为发送文件通常比10 sec更大,并且没有触发超时事件。但是此后始终在文件完全发送到服务器后立即发出超时事件。我能够在服务器端确认该文件已完全接收,并且发送了响应。但是,脚本未收到响应,因为超时事件是在触发之前的。

任何想法都将不胜感激!

您可以与XMLHttpRequestUpload对象一起使用Promise,特别是Promise.race方法。您可以有一个诺言是计时器,另一个等待XMLHttpRequest

var xhr = new XMLHttpRequest();
xhr.timeout = (1000 * 60) * 5 //5 minute initial timeout timer.
xhr.ontimeout = function() {
  doSomething(); //if 5 minute timeout is done.
};
var xhrUpload = xhr.upload;
xhrUpload.loadend = function() { //when upload is done, move on to 10s server timer.
raceThis(xhr, callback)
}
xhr.open('METHOD', url, true);
function raceThis(xmlReq, callback) {
  var waitForServer = new Promise(function(resolve, reject) {
    xmlReq.onreadystatechange = function() {
      if(xmlReq.readyState = 2) { 
        resolve(false); //the moment HTTP headers are sent as a response, resolve
      }
    }
  })
  var waitFor10Seconds = new Promise(function(resolve, reject) {
    window.setTimeOut(function() {
      resolve(true) 
    }, 10000)
  })
  Promise.race([waitForServer(), waitFor10Seconds()])
  .then(function(serverTimedOut) {
    if(serverTimedOut) {
      //do stuff if the server timed out 
    } else {
      //do stuff if the server didnt time out
    };
    callback(serverTimedOut) //you can even use dedicated callbacks! 
  })
}

这是一个粗略的表示,有很多方法可以扩展这一点,但这是主要思想。

亲爱的,您只能在发送请求之前设置超时值。一旦发送请求,就无法将其设置。我鼓励您避免为此类请求设置超时,因为您无法保证用户将上传什么文件大小。这是一个不好的做法。

很多事情可能会使请求需要更长的时间。例如由于其他一些原因(例如低内存(,浏览器倾向于悬挂,而另一个是网络连接速度很慢,另一个是服务器花费的时间太长,无法响应,由于漫长的运行脚本。对于具有快速Internet的设备,您的回调功能将更快地执行,您无法控制此功能,用户可以喜欢他的快速互联网,仅此而已。对于具有低速连接的其他人,他们知道那里的连接太慢了。

您还可以通过聆听进度事件并显示进度栏来监视进度,这将增强用户体验并使其生动活泼。

我不会建议您在一定时间间隔后流产请求,因为这是一个改变状态的操作。

相关内容

  • 没有找到相关文章

最新更新