Reputation: 497
So the API's response contains data
property which should contain the .zip file that i need. Its written in a format i do not understand.
I tried using .blob()
as referenced in similar questions here on Stackoverflow, but it doesn't seem to work.
The ideal solution is this: when client presses the button, he should be prompted to download said .zip file (the one from the HTTP response) locally. I'm using axios and the request type is PUT
.
My code example so far:
const exportCards = () => {
axios
.put(url, {
ids: ids,
})
.then((res) => {
return res.data.blob();
})
.then((blob) => {
var file = window.URL.createObjectURL(blob);
window.location.assign(file);
})
.catch((e) => console.log(e));
};
Upvotes: 6
Views: 26046
Reputation: 1277
Your problem is that you didn't explicitly specify the response type in your PUT
request. This should work:
const exportCards = () => {
axios
.put(url, {
ids: ids,
}, {
responseType: 'blob'
})
.then((res) => { // Now 'res.data' is Blob, not a string
var file = window.URL.createObjectURL(res.data);
window.location.assign(file);
})
.catch((e) => console.log(e));
};
Upvotes: 1
Reputation: 81
What I wanted:
My tools:
The problem I faced with:
Nothing helped me, probably because I did something wrong. But here is a simple and quick solution that I came up with:
//BE
const filename = "my-file-name.json";
const zip = new AdmZip();
zip.addFile(filename, body);
const content = zip.toBuffer();
res.set({
"Content-Length": Buffer.byteLength(content), //I'm not sure if this is necessary, but it's better to let it be :-)
"Content-Type": "text/plain",
"Content-Disposition": `attachment; filename=${filename}.${format}`,
});
res.status(200).send(content.toString("hex")); //my solution to the problem
//FE
const { headers, data } = await axios.post(myEndpoint);
const headerLine = headers["content-disposition"];
const filename = headerLine.replace(/[\w; ]+filename=/g, "");
const content = Buffer.from(data, "hex");
const blob = new Blob([content], { type: "application/zip" });
saveAs(blob, filename); //file-saver npm package
Upvotes: 3
Reputation: 3689
I would suggest fetch over axios in concern of zip file because sometimes the response in axios request is not accurate and you might fall into currupted zip file while downloading, the best might be using a package called file-saver and fetch. I am posting this answer to help the developers to grab the concept only, the code is tested in React.
package file-saver:https://www.npmjs.com/package/file-saver
Now make any function according to your choice in react, I am assuming functional component so will write method according to functional component syntax. note before using saveAs function you need to import from the installed package file-saver.
import { saveAs } from 'file-saver';
const downloadZipFileFromLaravel=()=>{
fetch(`your url`)
.then(res => res.blob())
.then(blob => saveAs(blob, 'Auto Photos.zip')) // saveAs is a function from the file-saver package.
.catch((err) => {
console.log(err.message);
});
}
at the end you need to connect the function with a button with onClick. example
<button onClick={()=>downloadZipFileFromLaravel()}> </button>
Note: usage of file saver in pure javascript, you can check this: How to use filesaver.js
For more information you can see the below discussion: Reference: https://github.com/eligrey/FileSaver.js/issues/156
Upvotes: -1
Reputation: 216
a
tag has download
attribute, in .then
you can try something like that
const url = new Blob([response.data],{type:'application/zip'});
const link = document.createElement('a');
link.href = url;
link.setAttribute('download', 'file.zip'); //set download attribute to link
document.body.appendChild(link);
link.click(); // this will download file.zip
Upvotes: 1