【vue】前后端分离模式vue + spring boot的文件下载方式

[业务场景]

前端上传附件到后端指定文件夹 /static/images 中,前端请求下载附件。

由于上传附件的名称和真实存放文件名称不一致,前端直接通过文件名请求下载的名字是随机生成的UUID名,对用户非常不友好。

因此,应当使用后端以文件流的形式返回下载。

[后端] Spring Boot 以文件流的形式返回

/*
     * 根据文件名进行文件下载
     * */
    @GetMapping("/download")
    public void fileDownload(String fileName, String fileNameUid, HttpServletResponse response) throws IOException {
        System.out.println("=======/column/download=======");
        System.out.println(fileName);
        System.out.println(fileNameUid);

        // 去数据库找真实文件名
        String realFileName = "20210328165114_79d30e1033fb4a6d9c8c572039e7c142.jpg";
        String downloadUrl = ResourceUtils.getURL("classpath:").getPath() + "\\static\\images";
        // 获取文件输入流
        FileInputStream fileInputStream = new FileInputStream(new File(downloadUrl, realFileName));
        // 附件下载
        response.setContentType("application/x-download;charset=utf-8");
        response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8")); // 下载返回的是文件原始名称
        // 获取响应输出流
        ServletOutputStream outputStream = response.getOutputStream();
        // 文件拷贝
        IOUtils.copy(fileInputStream, outputStream);
        IOUtils.closeQuietly(fileInputStream);
        IOUtils.closeQuietly(outputStream);
    }

[前端] Vue请求文件下载

#1-> 直接用<a>标签请求下载

 <a href="http://localhost:8080/column/download?fileName=下载.jpg" methods="get">下载附件</a>

原生的<a>样式太丑,可以用下面的方式进行封装,底层机制是一样的。

<el-link icon="el-icon-download" @click="downloadFile(file.acc_name, file.acc_name_uid)">{{ file.acc_name }}</el-link>
async downloadFile (fileName, fileNameUid) {
    const a = document.createElement('a')
    a.href = 'http://localhost:8080/column/download?fileName=' + fileName + '&fileNameUid=' + fileNameUid
    a.click()
}

#2-> axios-GET请求

      // 下载文件
      async downloadFile (fileName, fileNameUid) {
        console.log(fileName + ' ' + fileNameUid)
        const { data: res } = await this.$http.get('/column/download', {
          params: {
            fileName: fileName,
            fileNameUid: fileNameUid
          },
          responseType: 'blob' // 必须注明blob方式返回
        })
        console.log('======= /column/download =======')
        console.log(res)
        const url = window.URL.createObjectURL(new Blob([res]))
        const link = document.createElement('a')
        link.href = url
        link.setAttribute('download', '下载.jpg') // 下载文件的名称及文件类型后缀
        document.body.appendChild(link)
        link.click()
        document.body.removeChild(link) // 下载完成移除元素
        window.URL.revokeObjectURL(url) // 释放掉blob对象
      }

参考

https://www.jianshu.com/p/70816806e428

https://developer.mozilla.org/zh-CN/docs/Web/API/Blob/type

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值