Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I save a file getting downloaded from server using react?

Tags:

reactjs

I have one backend API which basically downloads a template whenever we call it. I have provided a href on my html page hence whenever someone click on that href, it calls backend API and that file should get downloaded.

But the file is not getting downloaded.

I am using React. If i simply hit the backend from my browser, file gets downloaded but if i call that from react, it doesn't.

Any leads?

REACT CODE :

const config = require('config');
var aws4 = require('aws4');
const Promise = require('axios');

const requestHelper = {
  appendHeaders(request){
    request.headers = request.headers || {};
    if(request.headers["Content-Type"]){
      return
    }
    request.headers["Content-Type"] = "application/json";
  },
  externalApi(request, serverResult){
    if(!request.method){
      request.method='POST';
    }
    request.path = request.url
    this.appendHeaders(request)
   console.log('request',request)
    return Promise(request)
    .then((apiResponse) => {
      if (apiResponse.data.errors) {
        var error = apiResponse.data.errors;
        console.log('api error response: ', error);
        serverResult.status(400).json({ error })
      } else {
        console.log('api response: ', apiResponse.data);
        serverResult.status(200).json(apiResponse.data);
      }
    }).catch((error) => {
      console.log('api error response: ', error);
      serverResult.status(400).json({ error });
    });
   },

   getDownloadResponse(request, serverResult){
    debugger;
    request.path = request.url
    this.appendHeaders(request)
    console.log(request);
    return Promise(request)
    .then((apiResponse) => {
      if (apiResponse.data.errors) {
        var error = apiResponse.data.errors;
        console.log('api error response: ', error);
        serverResult.status(400).json({ error })
      } else {
        serverResult.status(200);
        console.log('api response status: '+200);
      }
    }).catch((error) => {
      console.log('api error response: ', error);
      serverResult.status(400).json({ error });
    });
   }
};

module.exports = requestHelper;

BACKEND API CODE :

@RequestMapping(value = GlobalConstants.DOWNLOAD_FILE, method = RequestMethod.GET)
public void downloadTemplate(HttpServletRequest hRequest, HttpServletResponse response) throws Exception {

    InputStream in = null;
    OutputStream out = null;
    try {
        if (!StringUtils.isEmpty(sampleFile)) {
            File file = new File(sampleFile);
            in = finderService.downloadFile(sampleFile);
            if (in != null) {
                MimetypesFileTypeMap mimetypesFileTypeMap = new MimetypesFileTypeMap();
                response.setContentType(mimetypesFileTypeMap.getContentType(file));
                String headerKey = "Content-Disposition";
                String headerValue = String.format("attachment; filename=\"%s\"", file.getName());
                response.setHeader(headerKey, headerValue);

                out = response.getOutputStream();
                byte[] buffer = new byte[4096];
                int length;
                while ((length = in.read(buffer)) > 0) {
                    out.write(buffer, 0, length);
                }
            }
        } else {
        response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
        }
        logger.error("Internal Server error"); //Add logs for server error here also

    } catch (Throwable th) {
        response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
        logger.error(th);
        return;
    } finally {
        if (in != null) {
            in.close();
        }
        if (out != null) {
            out.flush();
        }
    }
}
like image 325
Ritu Bhandari Avatar asked Nov 20 '16 18:11

Ritu Bhandari


People also ask

How do I save a file in Reactjs?

You can use this https://www.npmjs.com/package/file-saver then save the file like this: saveAs(blob, 'filename') .

How do I download a PDF from Reactjs?

It is possible by using the fetch() method provided by Java Script. The PDF file will be placed in the public folder of React JS application folder structure. Approach: To accomplish this task we do not need to create any new component, we will use one single component named “App.

How do I download a text file from react?

To download a string as . txt file in React, we can convert the string into a blob. And then we can create a hidden link that has the blob's object URL set as the href attribute and click on the link programmatically to download it.


Video Answer


2 Answers

A GET request in JS is not the same as visiting a url in your browser. You need to directly invoke a download on the client by specifying an URL, for example like this:

download() {
  // fake server request, getting the file url as response
  setTimeout(() => {
    const response = {
      file: 'http://releases.ubuntu.com/12.04.5/ubuntu-12.04.5-alternate-amd64.iso',
    };
    // server sent the url to the file!
    // now, let's download:
    window.open(response.file);
    // you could also do:
    // window.location.href = response.file;
  }, 100);
}

Here it is as a working example on JSBin.

Note that if you want to download files that the browser can display (such as JSON, images, videos), they will be displayed in a new tab. If you want those types of files downloaded directly, you will need to use some workarounds, for example using blob. There are a few examples of this on here.

like image 180
Fabian Schultz Avatar answered Oct 11 '22 02:10

Fabian Schultz


You can use React 'a' element with href and download props:

 <a href={getFile.url}
    download={getFile.saveAsFileName}>
</a>
like image 18
Asaf Pinhassi Avatar answered Oct 11 '22 02:10

Asaf Pinhassi