Marko Marchisio
Marko Marchisio

Reputation: 497

How to download .zip file that i recieve from a HTTP response (axios PUT request)

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.

The format: enter image description here

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

Answers (4)

Roman
Roman

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));
};

enter image description here

Upvotes: 1

pi88a
pi88a

Reputation: 81

What I wanted:

  • send files of any formats from the back-end to the front-end

My tools:

  • axios, express, saveAs

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

Sabaoon Bedar
Sabaoon Bedar

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

Guram Khasia
Guram Khasia

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

Related Questions