首页 > 解决方案 > 为什么 XMLHttpRequest 中的 event.total 总是 0,除非 Content-Type 是 PDF?

问题描述

我尝试了好几天为我的下载制作进度条,我认为这项任务很简单。

一切似乎都恰到好处,但event.total-value 始终为 0(或undefined在 angular-version.

这基本上是文件通过的方式:

<?php // backend.php
if (isset($_GET["file"])) {
    $file = "dlstuff/{$_GET["file"]}";
}

$stream = fopen($file, 'rb');
header('Content-Length: '. filesize($file));
header("Content-Type: text/plain", true);

fpassthru($stream);

并且标题暴露在此处,.htaccess如下所述

Header add Access-Control-Expose-Headers "Content-Length"

我用这样的 Javascript 获得了文件:应用程序是用 Angular 编写的,但我可以用简单的纯 HTML 重现它:

  const oReq = new XMLHttpRequest();

  oReq.addEventListener("progress", oEvent => {
    console.log("progress");
    console.log({ loaded: oEvent.loaded, total: oEvent.total, status: oReq.status });
    console.log(oReq.getAllResponseHeaders());
  });

  oReq.addEventListener("load", () => {
    console.log("complete");
    console.log({ status: oReq.status, downloaded: oReq.response.length });
    console.log(oReq.getAllResponseHeaders());
  });

  oReq.open("GET", "http://localhost/backend.php?file=whatever.htm");

  oReq.send();

我读了很多东西

但是仍然 - 不event.total,并且Content-Length在浏览器控制台中不可见。

progress
(index):11 {loaded: 65536, total: 0, status: 200}
(index):12 access-control-expose-headers: Content-Length
connection: Keep-Alive
content-encoding: gzip
content-type: text/plain;charset=UTF-8
date: Mon, 13 Sep 2021 15:09:22 GMT
keep-alive: timeout=5, max=99
server: Apache/2.4.38 (Debian)
transfer-encoding: chunked
vary: Accept-Encoding

直到我将Content-TypePHP-Script 中的 -header更改为application/pdf 偶然. 突然就成功了!这是怎么回事?真实的应用程序可能有各种文件格式,但我想将它们全部视为 Javascript 端的文本。

--

编辑1:

`application/octet-stream` 而不是 Pdf 也可以。但问题仍然存在:为什么?

标签: javascriptphpxmlhttprequest

解决方案


推荐阅读