【问题标题】:How to download files using Springboot @RestController via ajax如何通过 ajax 使用 Spring Boot @RestController 下载文件
【发布时间】:2017-06-24 16:04:28
【问题描述】:

我有一个 Springboot 休息控制器来下载文件。我正在尝试使用浏览器访问端点并能够在 xhr.response 中看到响应。但是,我想强制下载我无法实现的文件。

代码如下: 基于 Rest 的端点(Springboot):

    @GetMapping(value = "download/{id}", produces = MediaType.APPLICATION_OCTET_STREAM_VALUE, consumes = "*/*")
public ResponseEntity<InputStreamResource> getFile(@PathVariable("id") Long contractId) {

    Contract contract;
    contract = this.contractRepository.findOne(contractId);
    System.out.println(contract.getPath()); // test
    InputStreamResource resource    = null;
    HttpHeaders         respHeaders = new HttpHeaders();

    if (contract != null) {

        try {
            File            file            = new File(contract.getPath());
            FileInputStream fileInputStream = new FileInputStream(file);
            resource = new InputStreamResource(fileInputStream);
            System.out.println(resource.exists());//test

            respHeaders.add("Content-Type", URLConnection.guessContentTypeFromStream(fileInputStream));
            respHeaders.add("Cache-Control", "no-cache, no-store, must-revalidate");
            respHeaders.add("Pragma", "no-cache");
            respHeaders.add("Expires", "0");
            respHeaders.add("Content-Disposition", "attachment;filename=" + file.getName());
            respHeaders.add("Content-Transfer-Encoding", "Binary");
            respHeaders.setContentLength(file.length());
        } catch (IOException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    return new ResponseEntity<InputStreamResource>(
            this.companyService.downloadContract(contractId),
            respHeaders,
            HttpStatus.OK
    );


}

我的xhr请求如下

 var xhr = new XMLHttpRequest();
 xhr.open("GET", http.getHRTargetURL() + "download/" + id, true);
 xhr.setRequestHeader("X-Auth-Token", http.getToken());
 xhr.setRequestHeader("Accept", "application/octet-stream");
 xhr.setRequestHeader("Content-Type", "application/octet-stream");
 
 xhr.onreadystatechange = function () {
     if (xhr.readyState == 4 && xhr.response != "0") {
         console.log(xhr)
         console.log("Downloaded file");
     } else {
        console.log("error downloading document")
     }
  }
xhr.send();

我能够从端点获得响应。我可以在浏览器的 xhr 响应中看到文件内容

我的问题是如何强制此响应以在浏览器上弹出文件保存向导。

【问题讨论】:

    标签: javascript xmlhttprequest


    【解决方案1】:

    你可以这样试试。

    xhr.onreadystatechange = function () {
         if (xhr.readyState == 4 && xhr.response != "0") {
             console.log(xhr)
            var windowUrl = window.URL || window.webkitURL;
            var url = windowUrl.createObjectURL(xhr);
            anchor.prop('href', url);
            anchor.prop('download', "filename");
            anchor.get(0).click();
            windowUrl.revokeObjectURL(url);
             console.log("Downloaded file");
         } else {
            console.log("error downloading document")
         }
      }
    xhr.send();
    

    【讨论】:

    • 有一个错字。您应该将 windowUrl 更改为 window.URL
    【解决方案2】:

    好吧,我发现问题出在前端,与后端无关,因为 Springboot 正在发送正确的响应。

    根据上面 Dinesh 提供的答案,我将我的答案修改如下

    download(id, name){
    
        var xhr = new XMLHttpRequest();
        xhr.open("GET", http.getHRTargetURL() + "download/" + id, true);
        xhr.setRequestHeader("X-Auth-Token", http.getToken());
        xhr.setRequestHeader("Content-Type", "application/octet-stream");
        xhr.responseType       = "blob";
    
        xhr.onreadystatechange = function () {
          if (xhr.readyState == 4) {
            var a = document.createElement("a");
            document.body.appendChild(a);
            a.style    = "display: none";
            var url    = window.URL.createObjectURL(new Blob([xhr.response], {type: "octet/stream"}));
            a.href     = url;
            a.download = name;
            a.click();
            window.URL.revokeObjectURL(url);
          } else {
            console.log("error downloading document")
          }
        }
        xhr.send();
    
      }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-11-11
      • 1970-01-01
      • 2016-07-08
      相关资源
      最近更新 更多