17

In my react app, I have a component which has a file download button for download a file coming from the Back end. I'm using AXIOS for the AJAX call. The problem is, after downloading the file, it is corrupted. I'm downloading png files and pdf files. When I open the downloaded image, it says it's corrupted and downloaded pdf shows white background only. How can I download a file correctly?

** Component:**

import API from "../../api/api";

class DocumentsTable extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      fileId: 4
    };
    this.downloadMapById = this.downloadMapById.bind(this);
  }

  downloadMapById() {
    const type = 1;
    const file_id = this.state.fileId;

    const FileDownload = require("js-file-download");

    API.post("project/files/download", { file_id, type })
      .then(({ data }) => {
        FileDownload(data, "myImage.png");
        console.log("success!", data);
      })
      .catch(err => {
        console.log("AXIOS ERROR: ", err);
      });
  }

  render() {
    return <button onClick={() => this.downloadMapById}>Download</button>;
  }
}

API file:

import axios from "axios";

const token = localStorage.getItem("token");

export default axios.create({
  baseURL: `${process.env.REACT_APP_BACKEND_BASE_URL}/api/v1/`,
  headers: {
    Authorization: "Bearer " + token,
    "Content-Type": "application/json",
    Accept: "application/json"
  }
});
Object object
  • 872
  • 6
  • 18
David Johns
  • 1,254
  • 3
  • 19
  • 48
  • You should download the file as binary not json – Dominic May 20 '19 at 11:07
  • @Dominic So should I set the Content type as binary or Octet stream? – David Johns May 20 '19 at 12:39
  • 1
    Correct - "The recommended action for an implementation that receives an "application/octet-stream" entity is to simply offer to put the data in a file" – Dominic May 20 '19 at 12:41
  • 2
    See this answer - https://stackoverflow.com/questions/49040247/download-binary-file-with-axios remember to add `responseType: 'arraybuffer',` and I think you can change Accept to a generic octet stream – Dominic May 20 '19 at 12:43
  • 1
    @Dominic Thank you! That answer solved my problem – David Johns May 20 '19 at 15:58

1 Answers1

16

As I am not able to add comments so posting as answer. I have tried the same thing and posted the question for same in this link.

For post method i get the success with fetch as below.

 fetch("url",
        { 
            method: "POST",
            headers: { "Content-Type": "application/json",'Authorization': 'Bearer ' + window.localStorage["Access_Token"]},
            body:data
        }).then(response => response.blob()).then(response => ...*your code for download*... )

You are getting corrupted file because you are not receiving content as blob or arraybuffer.

Sandeep Rasgotra
  • 582
  • 1
  • 7
  • 18