I want to receive a zip file as a string from an Ajax request and then hold it in memory so it can be downloaded multiple times if necessary so that only the one request is sent.
I tried to download it with this:
zip_string = 'PK etc.'
function download(filename, text) {
var element = document.createElement('a');
element.setAttribute('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent(text));
element.setAttribute('download', filename);
element.style.display = 'none';
document.body.appendChild(element);
element.click();
document.body.removeChild(element);
}
// Start file download.
download("zip1.zip", zip_string);
It came through as a zip but then there was obviously a problem because it wouldn't open. Can anyone see what I'm doing wrong?
I solved the problem by encoding the zip file string as base64 on the server before it gets sent through.
with open(file, "rb") as f:
bytes = f.read()
encoded = base64.b64encode(bytes)
And then in the JS I just specify that it's base64:
zip_string = 'UEsDBBQAAAAIANQzCU0J56mLPAIAAD4VAAAOAAAA etc.'
function download(filename, data) {
var element = document.createElement('a');
element.setAttribute('href', 'data:text/plain;base64,' + data);
element.setAttribute('download', filename);
element.style.display = 'none';
document.body.appendChild(element);
element.click();
document.body.removeChild(element);
}
// Start file download.
download("zip1.zip", zip_string);
The data type of your link's href
is plain text (ie as specified by data:text/plain
) which basically means, the contents of the link will be treated by the browser as plain text.
A zip archive is a binary format - you will need to do a bit more work to generate a real zip file and then cache it client side, in this way. You may want to look at zip.js as a library to help you with this.
You can however make a simple change to get the download function working - just change "zip1.zip"
to "zip1.txt"
. I've prepared a jsFiddle here if you to see this in action.
Hope that helps!
Using JSZip package: https://stuk.github.io/jszip/
public async downloadFile(filename: string, content: string) {
const zip = new JSZip();
await zip.loadAsync(content, {base64: true});
const blob = await zip.generateAsync({type:"blob"});
const element = document.createElement("a");
element.setAttribute("href", window.URL.createObjectURL(blob));
element.setAttribute("download", filename);
element.style.display = "none";
document.body.appendChild(element);
element.click();
document.body.removeChild(element);
}
const fileName = "test.zip";
const content = "UEsDBAoAAAAAAI5ONE9i6ZVwCQAAAAkAAAAIAAAAdGVzdC50eHRUZXN0IGZpbGVQSwECPwAKAAAAAACOTjRPYumVcAkAAAAJAAAACAAkAAAAAAAAACAAAAAAAAAAdGVzdC50eHQKACAAAAAAAAEAGABz76T2f2/VAXPvpPZ/b9UB1NBncjhp1QFQSwUGAAAAAAEAAQBaAAAALwAAAAAA"; // base64 content without mimeType
this.downloadFile(fileName, content);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With