如何使用fetch API在JavaScript中下载具有多个块的单个文件

3
我在我的React应用程序中使用fetch API从URL下载文件。每个URL提供一个响应块。当文件只有一个块时,我可以使用response.blob()下载文件。但是,如果对于单个文件有多个块,则必须从n个不同的URL(例如url1、url2等)获取块。如何组合它们的响应以生成单个blob并下载文件。
以下是仅使用一个块(从url-1获取)下载文件的代码。
let downloadUrl = `https://url-1`;
      fetch(downloadUrl, {
        method: 'GET'
      })
        .then(
          (res: any) => {
            if (res.ok && res.status === 200) {
              //File response loaded
            } else {
              return null;
            }
            return res.blob();
          },
          error => {
            // error in downloading
          }
        )
        .then(fileData => {
          if (fileData) {
            let url = window.URL.createObjectURL(fileData);
            let a = document.createElement('a');
            a.href = url;
            a.download = file.fileName;
            a.click();
          }
        });

我可以在Fetch API中进行多个请求,并使用 Promise.all(responseArr)。但是如何将它们的响应合并成单个 blob 响应呢?
2个回答

4
您可以使用fetch()获取单个块,然后使用.arrayBuffer()将每个响应作为数组缓冲区获取。

然后,您可以使用Blob(array, options)构造函数创建一个新的 Blob,其中包含您刚刚下载的所有数组缓冲区。

示例:

// fetch chunks from somewhere
let urls = ["http://foo.bar/chunk/1", "http://foo.bar/chunk/2"];
let chunkPromises = urls.map(url => {
  return fetch(url).then(res => {
    return res.arrayBuffer();
  });
});

Promise.all(chunkPromises).then(chunks => {
  // combine chunks into a single blob
  let blob = new Blob(chunks, {
    // Optional: specify the MIME Type of your file here
    type: "text/plain" 
  });

  // download the blob
  let url = window.URL.createObjectURL(blob);
  let a = document.createElement('a');
  a.href = url;
  a.download = "Filename.txt";
  a.click();
});

2
我会遍历URL以按顺序下载分块,并在下载时将它们合并。
try{
    var urls = ['https://url-1','https://url-2.0','https://url-3.1415']
    var fullFile = new Blob();
    for (let x = 0; x < urls.length; x++){
        await fetch(urls[x]).then((res) => {
            if (!res.ok || res.status !== 200) {
                throw('Download failed');
            }
            return res.blob();
        }).then(data => fullFile = new Blob([fullFile, data]));
    }
    let url = window.URL.createObjectURL(fullFile);
    let a = document.createElement('a');
    a.href = url;
    a.download = file.fileName;
    a.click();
} 
catch(e){console.log(e)};

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接