SpringBoot中jQuery.ajax文件下载


placeholder image
admin 发布于:2024-07-21 18:03:08
阅读:loading

作为一名不特专业的前端选手,在之前的文件下载均使用window.location.href(同超链接)或form表单提交的方式进行的,这种认知取决于多年前的落后经验,从IE6、IE7、IE8的时代经过,确实没办法使用Ajax下载文件,以至于到HTML5成熟后也没有再深入细致的研究Ajax是否能够支持文件上传和下载的实现,最关键的是无论上传还是下载都可以不通过Ajax的方式实现页面无刷新,所以是否使用的Ajax就显得不那么重要了。

1.简单介绍

如上所述的文件下载方式使用了多年,一直都存在一种场景的弊端,那就是当文件下载成功后执行一个方法的回调,而近期参与一次前端会议时提出了这么一个疑问,得到了Ajax可以下载文件的答复,于是就有了一个基于Ajax下载文件的实现,同时将这几年使用到的Ajax上传文件也同样给整理出来了,本篇以下载为主(上传可见前一篇文章),详细如下:

本次实践将新建一个纯净的SpringBoot项目,提供文件两种文件下载处理Controller实现,相关细节知识如下:

(1)基于jQuery的文件下载,即:$.ajax实现;

(2)后端使用SpringBoot项目架构,纯净的项目工程;

(3)后端提供两种方式来输出文件,并提供文件下载相关的Response Header响应;

(4)使用Ajax下载文件的实际文件名称可由后端返回,也可以不依赖于后端,本次示例为了简单直接使用encodeURI进行的编码和解码,解决文件中文问题;

2.参考代码

(1)文件下载方式1

@GetMapping("/yml")
public void download(HttpServletResponse response) throws IOException {
    String attachment = ContentDisposition.attachment().filename(URLEncoder.encode("application.yml" , StandardCharsets.UTF_8.name())).build().toString();
    response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);
    response.setHeader(HttpHeaders.CONTENT_DISPOSITION , attachment);
    try (InputStream inputStream = getClass().getResourceAsStream("/application.yml");
         ServletOutputStream outputStream = response.getOutputStream()) {
        assert inputStream != null;
        StreamUtils.copy(inputStream , outputStream);
    }
}

(2)文件下载方式2

@GetMapping("/class")
public ResponseEntity<byte[]> download() throws Exception {
    HttpHeaders headers = new HttpHeaders();
    headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
    headers.setContentDisposition(ContentDisposition.attachment().filename(URLEncoder.encode("中文文件名Controller.class" , StandardCharsets.UTF_8.name())).build());
    try (InputStream inputStream = getClass().getResourceAsStream(AjaxDownloadController.class.getSimpleName() + ".class")) {
        return ResponseEntity.ok().headers(headers).body(StreamUtils.copyToByteArray(inputStream));
    }
}

(3)前端下载实现

<script type="text/javascript">
    $(function() {
        $("#download_1_id").click(function() {
            downloadSubmit("/ajax/download/yml");
        })
        $("#download_2_id").click(function() {
            downloadSubmit("/ajax/download/class");
        })
    });

    function downloadSubmit(url) {
        $.ajax({
            url: url,
            type: 'get',
            dataType: "*",
            xhrFields: {
                responseType: "blob",
            },
            success: function (result , status , xhr) {
                const blob = new Blob([result], {
                    type: xhr.getResponseHeader("Content-Type"),
                });
                debugger;
                let fileName = xhr.getResponseHeader("Content-Disposition").replace('attachment; filename="' , "").replace('"' , "");
                const link = document.createElement("a");
                link.href = window.URL.createObjectURL(blob);
                link.download = decodeURI(fileName);
                document.body.appendChild(link);
                link.click();
                document.body.removeChild(link);
            },
            error: function (xhr, status, error) {
                alert("文件下载失败,状态码:" + status.statusCode + ",参考信息:" + status.statusText);
            }
        });
    }

</script>

3.运行示例

Ajax文件下载-含水印.gif

4.源码下载

源码下载.zip

 点赞


 发表评论

当前回复:作者

 评论列表


留言区