0

I tried various days to make a progress bar for my download, a task which I expected to be quite trivial.

Everything seemed to to be just right, but the event.total-value was always 0 (or undefined in the angular-version.

This is basically how the file got passed:

<?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);

And the header was exposed in .htaccess as stated here:

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

I obtained the file with Javascript like this: The application was written in angular, but I could reproduce it with simple plain 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();

I read a lot of stuff

But still - no event.total and the Content-Length was not visible in the browser-console.

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

I started to loose my mind overt this until I changed the Content-Type-header in the PHP-Script to application/pdf by accident. Suddenly it worked! What it going on? The real application may have various file formats but I would like to treat them all as text from the Javascript side.

--

Edit 1:

`application/octet-stream``instead of Pdf works as well. But the question remains: why?

Paflow
  • 2,030
  • 3
  • 30
  • 50
  • Using `Access-Control-Expose-Headers` should not be necessary (any more, that question you linked to is several years old) - `Content-Length` is a CORS-safelisted response header, meaning it gets exposed by default. – CBroe Sep 14 '21 at 07:40
  • Wondering if `content-encoding: gzip` has something to do with the problem perhaps? Try and disable that, and see if anything changes. – CBroe Sep 14 '21 at 07:41
  • @CBroe I tried `'accept-encoding': 'identity', and 'Content-type': 'text/plain'` to deactivate `gzip` but nothing changed. – Paflow Sep 14 '21 at 08:50

0 Answers0