最新消息:Welcome to the puzzle paradise for programmers! Here, a well-designed puzzle awaits you. From code logic puzzles to algorithmic challenges, each level is closely centered on the programmer's expertise and skills. Whether you're a novice programmer or an experienced tech guru, you'll find your own challenges on this site. In the process of solving puzzles, you can not only exercise your thinking skills, but also deepen your understanding and application of programming knowledge. Come to start this puzzle journey full of wisdom and challenges, with many programmers to compete with each other and show your programming wisdom! Translated with DeepL.com (free version)

javascript - Spring Rest and jQuery Ajax File Download - Stack Overflow

matteradmin5PV0评论

I am currently working with jQuery and Spring Rest. jQuery is used to upload and download files to the Server. The upload process is working fine but I have little problem with downloading the files. So the scenario is, in the view, the user will select the n numbers of files to download and clicks the download button. Once the user clicks that button, the files will be downloaded. I do not want to open a new new tab for each file download. I would like to download on the same window without refreshing the current view. I looked into this but didn't help me much. Is there any way, I can achieve this?

I am currently working with jQuery and Spring Rest. jQuery is used to upload and download files to the Server. The upload process is working fine but I have little problem with downloading the files. So the scenario is, in the view, the user will select the n numbers of files to download and clicks the download button. Once the user clicks that button, the files will be downloaded. I do not want to open a new new tab for each file download. I would like to download on the same window without refreshing the current view. I looked into this but didn't help me much. Is there any way, I can achieve this?

Share Improve this question edited May 23, 2017 at 11:59 CommunityBot 11 silver badge asked Oct 7, 2015 at 14:58 Rana_SRana_S 1,5503 gold badges23 silver badges40 bronze badges
Add a ment  | 

2 Answers 2

Reset to default 2

Here is my solution to download the file:

Spring Controller method:

@RequestMapping(value = "/download", method = RequestMethod.GET)
public void retrieveDocument(@RequestParam("id") String id, HttpServletResponse response) throws IOException {
    InputStream in = fileService.getFileStream(); // My service to get the stream.
    response.setContentType(MediaType.APPLICATION_OCTET_STREAM);
    response.setHeader("Content-Transfer-Encoding", "binary");
    response.setHeader("Content-Disposition", "attachment; filename=" + filename);
    try {
        IOUtils.copy(inputStream, response.getOuputStream()); //Apache mons IO.
        inputStream.close();
        response.flushBuffer();
        response.setStatus(HttpServletResponse.SC_OK);
    } catch (Exception e) {
        //log error.
    }

}

On client side function:

function download(id) {
    var id = $('#file').attr('id')
    var xhr = new XMLHttpRequest();
    xhr.open('GET', 'url here' + id, true);
    xhr.responseType = 'arraybuffer';
    xhr.onload = function() {
        if(this.status == '200') {
           var filename = '';
           //get the filename from the header.
           var disposition = xhr.getResponseHeader('Content-Disposition');
           if (disposition && disposition.indexOf('attachment') !== -1) {
               var filenameRegex = /filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/;
               var matches = filenameRegex.exec(disposition);
               if (matches !== null && matches[1])
                   filename = matches[1].replace(/['"]/g, '');
           }
           var type = xhr.getResponseHeader('Content-Type');
           var blob = new Blob([this.response],  {type: type});
           //workaround for IE
           if(typeof window.navigator.msSaveBlob != 'undefined') {
               window.navigator.msSaveBlob(blob, filename);
           }
           else {
               var URL = window.URL || window.webkitURL;
               var download_URL = URL.createObjectURL(blob);
               if(filename) {
                   var a_link = document.createElement('a');
                   if(typeof a_link.download == 'undefined') {
                       window.location = download_URL;
                   }else {
                       a_link.href = download_URL;
                       a_link.download = filename;
                       document.body.appendChild(a_link);
                       a_link.click();
                   }
               }else {
                   window.location = download_URL;
               }
               setTimeout(function() {
                   URL.revokeObjectURL(download_URL);
               }, 10000);
           }
        }else {
            alert('error')';//do something...
        }
    }; 
    xhr.setRequestHeader('Content-type', 'application/*');
    xhr.send();
}

I answered something similar a few minutes ago: sending file from response to user, Spring REST + jQuery


I remend you to use this JS plugin https://github./johnculviner/jquery.fileDownload to download the file instead using $.ajax directly. You can find all the official documentation there.

Also, in your controller, you have to take your HttpServletResponse and write the byte[] in the outputstream, and you have to put a cookie in the response to advise the JS plugin (because it needs it)

For example:

@RequestMapping(value = "/download", method = RequestMethod.GET)
    public void getFilesInZIP(@RequestParam("filenames[]") String[] filenames, HttpServletResponse httpServletResponse){
        byte[] file = service.packFilesToZIPArchiveAndReturnAsByteArray(filenames);

        Cookie cookie = new Cookie("fileDownload", "true");
        cookie.setPath("/");

        httpServletResponse.addCookie(cookie);
        httpServletResponse.setContentType("application/zip");
        httpServletResponse.setHeader("Content-Disposition", "attachment;filename=files.zip");
        httpServletResponse.getOutputStream().write(file);

    }
Post a comment

comment list (0)

  1. No comments so far