I am using fetch
API in my react app to download a file from a URL. Each URL provides one chunk as the response. When the file has only one chunk, i can use the response.blob()
to download the file. However if there are multiple chunks for a single file,i have to fetch the chunks from n different urls, say url1,url2,..so on. How can I bine their responses to generate a single blob and download the file.
Below is the code to download the file with only one chunk(fetched from 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();
}
});
I can make multiple requests in the fetch API and use Promise.all(responseArr)
. But how to bine their responses into single blob response ?
I am using fetch
API in my react app to download a file from a URL. Each URL provides one chunk as the response. When the file has only one chunk, i can use the response.blob()
to download the file. However if there are multiple chunks for a single file,i have to fetch the chunks from n different urls, say url1,url2,..so on. How can I bine their responses to generate a single blob and download the file.
Below is the code to download the file with only one chunk(fetched from 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();
}
});
I can make multiple requests in the fetch API and use Promise.all(responseArr)
. But how to bine their responses into single blob response ?
2 Answers
Reset to default 4You could get the individual chunks with fetch()
and then get each response as an array buffer with .arrayBuffer()
.
Then you can use the Blob(array, options)
constructor to create a new blob consisting of all the arraybuffers you just downloaded.
Example:
// 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 => {
// bine 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();
});
I would loop through the URLs to download the chunks in order and bine them as they download
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)};