Front end usage function: the front end directly requests the back-end stream to download files

Recently, the project encountered a small requirement that the file name is provided by the back end when the front end downloads a file (it turned out that the front end writes the file name dead). Our project architecture is SpringBoot+React (TypeScript). I looked at the back-end code and inserted the file name into the header of the response. The front end only needs to get the file name from the response header. The back-end setting response header code is as follows:

... ... 
try {
    fileName = new String(fileName.getBytes(), "ISO8859-1");
} catch (UnsupportedEncodingException e) {
    log.error("This document[{}]This encoding conversion is not supported,Exception message:[{}]", fileName, e.getMessage());
}
response.setHeader("Content-Disposition", "attachment;filename=" + fileName);
... ... 

As an aside, why should we encode the file name in the format of "ISO8859-1" and also respond to the file name in the format of content disposition in the header. The reason is that the project we originally wrote is not separated from the front end and the front end directly sends an ajax request to download. The browser will recognize the content disposition attribute and automatically configure the name of "filename =". And it needs to be encoded in "ISO8859-1" format, otherwise it will be garbled at noon. But our current project is the separation of front and rear ends. Each time you download a file, the front end requests the back end. After you get the data, simulate a click to download and return it to the user.

We know that there is a file name in the response header, so we need to get the response header. But I have a problem here: the header of the response obtained by the code is empty, but the browser F12 can see the header of the response. After some positioning and searching. It is found that the problem is due to the cross domain problem of the browser and the lack of configuration parameters. The specific solutions are as follows (java cross domain configuration class):

...  ... 
//Which header s can be exposed externally as part of the response
res.setHeader("Access-Control-Expose-Headers", "*");
...  ... 

After solving the above problems, the front end can normally obtain the file name. However, it also encountered the problem of Chinese garbled file names. After some attempts, the file name is parsed into normal Chinese. The specific processing is as follows (TypeScript front-end code):

let fileName;
const disposition = response.headers.get('Content-Disposition');
if (disposition === undefined || disposition == null) {
    fileName = 'Error ';
} else {
    fileName = decodeURI(escape(response.headers.get('Content-Disposition').split(';')[1].split('filename=')[1]));
}

The complete front-end code is as follows:

/**
 * File download
 *
 *
 * @param response
 * @param mimeEnum
 */
export function downLoadFileNew(response: any, mimeEnum: MimeEnum) {

  let fileName;
  const disposition = response.headers.get('Content-Disposition');
  if (disposition === undefined || disposition == null) {
    fileName = 'Error ';
  } else {
    fileName = decodeURI(escape(response.headers.get('Content-Disposition').split(';')[1].split('filename=')[1]));
  }
  const blob = new Blob([response], {type: mimeEnum});
  const a = document.createElement('a');
  a.download = fileName;
  a.href = window.URL.createObjectURL(blob);
  a.click();
};


/**
 *
 * Mime enumeration
 */
export enum MimeEnum {
  ZIP = 'application/zip',
  JPEG = "image/jpeg",
  PNG = "image/png",
  PDF = 'application/zip',
  DOC = "application/msword",
  DOCX = "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
  XLS = "application/vnd.ms-excel",
  XLSX = 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
  PPT = "application/vnd.ms-powerpoint",
  PPTX = "application/vnd.openxmlformats-officedocument.presentationml.presentation",
}

Keywords: Front-end React Back-end

Added by cytech on Sun, 02 Jan 2022 03:10:13 +0200