Skip to content

Instantly share code, notes, and snippets.

@merlosy
Created April 27, 2023 20:02
Show Gist options
  • Save merlosy/b7fd9905ef40955532978b6e75cd960c to your computer and use it in GitHub Desktop.
Save merlosy/b7fd9905ef40955532978b6e75cd960c to your computer and use it in GitHub Desktop.
File download snippets
/** Download a file from Blob and clean up memory */
export function downloadBlob(blob: Blob, filename: string | null = null): void {
const url = window.URL.createObjectURL(blob);
const a = document.createElement('a');
a.setAttribute('href', url);
a.setAttribute('download', filename || 'download');
document.body.appendChild(a);
// Prevent E2E from actually downloading files during test runs
if (!isE2ETesting()) {
a.click();
}
document.body.removeChild(a);
window.URL.revokeObjectURL(url);
}
/** @see https://itnext.io/how-to-download-files-with-javascript-d5a69b749896 */
export function downloadWithProgress(imgUrl: string, fileName: string) {
const startTime = new Date().getTime();
const request = new XMLHttpRequest();
request.responseType = 'blob';
request.open('get', imgUrl, true);
request.send();
request.onreadystatechange = () => {
if (request.readyState === XMLHttpRequest.DONE) {
const status = request.status;
if (status === 0 || (status >= 200 && status < 400)) {
// The request has been completed successfully
const imageURL = window.URL.createObjectURL(request.response);
const anchor = document.createElement('a');
anchor.href = imageURL;
anchor.download = fileName;
document.body.appendChild(anchor);
anchor.click();
// Clean up
document.body.removeChild(anchor);
window.URL.revokeObjectURL(imageURL);
} else {
// There has been an error with the request
throw new Error('Download request failed');
}
}
};
request.onprogress = event => {
const percent_complete = Math.floor((event.loaded / event.total) * 100);
const duration = (new Date().getTime() - startTime) / 1000;
const bps = event.loaded / duration;
const kbps = Math.floor(bps / 1024);
const time = (event.total - event.loaded) / bps;
const seconds = Math.floor(time % 60);
const minutes = Math.floor(time / 60);
console.log(`${percent_complete}% - ${kbps} Kbps - ${minutes} min ${seconds} sec remaining`);
};
request.onerror = event => {
throw new Error('Download request failed');
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment