【问题标题】:JScript/VBscript: Tracking file download progress via XMLHttpRequestJScript/VBscript:通过 XMLHttpRequest 跟踪文件下载进度
【发布时间】:2013-05-16 23:10:33
【问题描述】:

我正在开发一个 JScript/VBScript HTML 应用程序(因此我们可以以比普通网页更高的权限执行),我们正在提供下载文件的功能,并且需要向我们的用户提供有关下载进度的反馈。自然地,我根据总文件大小和已下载文件的数量计算了一个进度条或进度文本。我正在尝试在 Internet Explorer 中获取已下载部分的大小。到目前为止,我已经尝试了所有我能想到的方法来访问已经下载了多少文件。在readyState 3(交互式)期间尝试访问responseText或responseBody时,我只是得到了异常:

完成此操作所需的数据尚不可用。

因此,当他们记录下 responseText 或 responseBody 在 XMLHttpRequest 完成之前将不可用(进入 readyState 4)时,微软似乎没有撒谎

我可以获得总文件大小并将文件保存到磁盘,因此我省略了我已经拥有的代码部分。这是我一直在尝试的。我愿意接受任何其他建议——甚至改变 XMLHttpRequest 的实现。请注意,我无法控制服务器端...只有我的客户端应用程序,因此 php/ASP 解决方案将不起作用。 提前谢谢...

function getRemoteFile(urlToFile){
  if (urlToFile)    {
    try         {
      var xmlReq = new XMLHttpRequest();
      //Tried all of the following with no luck
    //var xmlReq = new ActiveXObject('Microsoft.XMLHTTP');
    //var xmlReq = new ActiveXObject('Msxml2.DOMDocument.3.0');
    //var xmlReq = new ActiveXObject("Msxml2.XMLHTTP.3.0");
    //var xmlReq = new ActiveXObject("Msxml2.XMLHTTP.6.0");
    //var xmlReq =new ActiveXObject("Msxml2.DOMDocument.6.0");

      function updateDownloadProgress() {                     
        if (xmlReq.readyState == 3) {
            try {
              alert(xmlReq.responseText.length);

            }
            catch (e) {
            alert(e.message);
            }          
          window.setTimeout(updateDownloadProgress, 200);
        }
      }                    

      xmlReq.open("GET", urlToFile, true);
      xmlReq.onreadystatechange = function(){
        if (xmlReq.readyState == 3)      {
          updateDownloadProgress();
        }
        if (xmlReq.readyState == 4)      {
          alert("done");
        }
      }
      xmlReq.send(null);
    } catch(e) {
      alert(e.message);
      return null;
    }
  }
}

【问题讨论】:

  • 如果微软曾经给你这个功能,它会像这样xkcd.com/612 :)

标签: internet-explorer xmlhttprequest javascript


【解决方案1】:

您可以在 IE 中仅显示 XML 文档的下载进度,使用 ondataavailable 事件:

var xmlDoc = new ActiveXObject("MSXML2.DOMDocument.3.0");
xmlDoc.ondataavailable = ondataavailable;
xmlDoc.async = true;
xmlDoc.load(url);

function ondataavailable() {
    ...
}

XML 在完全加载之前变得可用。要显示进度,您需要在服务器端的第一个 XML 节点中放置节点数,并在新的 XML 到达时计算节点数。

我知道这仅对 XML 文档有帮助,而且您必须能够修改服务器 xml 添加节点数。但据我所知,这是以某种方式在 IE 中显示进度的唯一方法。

请注意,如果服务器返回非 xml 内容,ondataavailable 永远不会触发。

【讨论】:

    【解决方案2】:

    在检查下载进度时添加一个 try/catch 块。确保在服务器可用时刷新数据,一些服务器/服务器脚本会缓冲内容。

    【讨论】:

    • 我不知道这会有什么帮助 - 即使数据已刷新,在多 MB 下载时,您通常也不会获得可靠的下载进度指示器。你能详细说明吗?谢谢。
    【解决方案3】:

    我认为您不能直接执行此操作,因为在收到所有内容之前,您不会在客户端获得进度更新(至少,不是以简洁的跨浏览器方式)。但是,您可以在服务器端告诉您已将多少文件写入响应。因此,一种方法是通过第二个 AJAX 调用使写入特定下载请求的响应的数量并行可用。因此,给每个下载一个 ID,存储通过该 ID 可找到的下载状态服务器端,并调用单独的并行 AJAX 请求来查询该 ID 的进度。然后以您想要的任何方式显示它 - 进度条、显示完成百分比的标签等。

    有关readyState == 3 周围问题的讨论,请参阅this post

    【讨论】:

      【解决方案4】:

      迟到总比没有好...添加答案...

      今天我通过尝试发现,在完全加载之前,您无法访问“Microsoft.XMLHTTP”的内容——而且很可能是所有其他 XMLHTTP 衍生物。

      但是,您可以在加载“internetExplorer.application”时实时访问它的内容。 但我想对于 web 开发者来说,这个对象没有那么灵活。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-06-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多