相同 URL 的提取响应大小不同

fetch response is not of same size for same URL

我正在使用 fetch API 从服务器获取响应 URL 并且响应大小并非每次都如此。

大多数时候我得到大小为 262144 的响应数据,但有时大小小于该大小。喜欢大小为 65536 和 196608 的数据。

async function fetchData() {
  let url = "https://www.dl.dropboxusercontent.com/s/7d87jcsh0qodk78/fuel_64x64x64_uint8.raw?dl=1";
  let response = await fetch(url);
  let data = await response.body.getReader().read();
  data = data.value;
  if (data) {
    dataBuffer = new Uint8Array(data);
    console.log(data.length);
  } else {
    console.log("action aborted");
  }
}

fetchData()

@3limin4t0r 的回答是正确的。问题不是由 Dropbox 压缩的文件引起的,而是由于 .read() 方法 returns 一个字节流,以及一个承诺...

"provid[es] access to the next chunk in the stream's internal queue."

您检索的值有时只是 stream/queue 中的第一个块。您必须等到 reader 完成流的读取。

您从 getReader() works with an internal queue. The documentation of read() 收到的 reader 内容如下:

The read() method of the ReadableStreamDefaultReader interface returns a promise providing access to the next chunk in the stream's internal queue.

多次获取最终可能会对远程数据进行不同的分块,从而导致不同的长度。要完成读取流,请检查 read().

返回的 done

async function fetchData() {
  const url = "https://www.dl.dropboxusercontent.com/s/7d87jcsh0qodk78/fuel_64x64x64_uint8.raw?dl=1";
  const response = await fetch(url);
  const reader = response.body.getReader();
  
  let length = 0;
  let value, done;
  while ({value, done} = await reader.read(), !done) {
    length += value.length;
  }
  console.log(length);
}

fetchData()

但是,如果目的是在采取任何操作之前读取流直到完成,您不妨根据您期望的数据类型使用 arrayBuffer(), blob(), formData(), json() or text() 等响应方法之一。提到的响应方法都是读取响应流完成。

async function fetchData() {
  const url = "https://www.dl.dropboxusercontent.com/s/7d87jcsh0qodk78/fuel_64x64x64_uint8.raw?dl=1";
  const response = await fetch(url);
  const dataBuffer = new Uint8Array(await response.arrayBuffer());
  
  console.log(dataBuffer.length);
}

fetchData()