后端代码:

@GetMapping("/{sn}")
@ApiOperation(value = "获取文件",notes = "获取文件")
public void downloadFile(@PathVariable String sn, HttpServletResponse response) throws Exception {
SysFileEntity sysFile = fileService.findBySn(sn);
if (sysFile != null){
File file = new File(sysFile.getFilePath());
if (file.exists()){
// 设置强制下载不打开
response.setContentType("application/force-download");
// 设置文件名
response.addHeader("Content-disposition", "attachment;fileName=" + URLEncoder.encode(file.getName(), StandardCharsets.UTF_8));
response.addHeader("Access-Control-Expose-Headers", "Content-Disposition");
FileInputStream fis = null;
BufferedInputStream bis = null;
byte[] buffer = new byte[1024];
try {
fis = new FileInputStream(file);
bis = new BufferedInputStream(fis);
OutputStream os = response.getOutputStream(); int i = bis.read(buffer);
while (i != -1) {
os.write(buffer, 0, i);
i = bis.read(buffer);
} }
finally {
if (bis != null) {
try {
bis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (fis != null) {
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}

前端代码:

//封装的axios
this.$http.request({
method: "get",
url: `${this.$apis.common.file}/${this.ruleForm.fileSN}`,
data: {},
//此处可以无视,前端封装全局加载遮罩
loading: false,
responseType: 'blob'
}).then(res => { const fileName = decodeURIComponent(res.headers["content-disposition"]).split("=")[1];
const _res = res.data;
let blob = new Blob([_res]);
let downloadElement = document.createElement("a");
//创建下载的链接
let href = window.URL.createObjectURL(blob);
downloadElement.href = href;
//下载后文件名
downloadElement.download = fileName;
document.body.appendChild(downloadElement);
//点击下载
downloadElement.click();
//下载完成移除元素
document.body.removeChild(downloadElement);
//释放掉blob对象
window.URL.revokeObjectURL(href); })

常见问题总结

  1. 前端接收到的响应头中不包含 “content-disposition”,但是在浏览器的网络中可以看到,这里需要后端在响应头中增加

    response.addHeader("Access-Control-Expose-Headers", "Content-Disposition");
  2. 文件名返回到前端后乱码

    此处需要在后端对文件名转码

    //StandardCharsets.UTF_8 等价于"UTF8"
    URLEncoder.encode(file.getName(), StandardCharsets.UTF_8)

    在前端文件解码

    此处是把整个 “content-disposition”响应头的内容解码后再取文件名。也可以先取文件名再解码

    decodeURIComponent(res.headers["content-disposition"])
  3. 注意自己的前端框架里封装的axios是否有返回数据的拦截处理

    我这里因为需要与后端进行身份验证所以还是用的框架内封装好的请求方法。但是需要对返回的文件数据与其他区分出来

Spring boot + Vue axios 文件下载的更多相关文章

  1. spring boot + vue + element-ui全栈开发入门——基于Electron桌面应用开发

     前言 Electron是由Github开发,用HTML,CSS和JavaScript来构建跨平台桌面应用程序的一个开源库. Electron通过将Chromium和Node.js合并到同一个运行时环 ...

  2. spring boot + vue + element-ui

    spring boot + vue + element-ui 一.页面 1.布局 假设,我们要开发一个会员列表的页面. 首先,添加vue页面文件“src\pages\Member.vue” 参照文档h ...

  3. Spring Boot + Vue 跨域请求问题

    使用Spring Boot + Vue 做前后端分离项目搭建,实现登录时,出现跨域请求 Access to XMLHttpRequest at 'http://localhost/open/login ...

  4. spring boot + vue + element-ui全栈开发入门——开篇

    最近经常看到很多java程序员朋友还在使用Spring 3.x,Spring MVC(struts),JSP.jQuery等这样传统技术.其实,我并不认为这些传统技术不好,而我想表达的是,技术的新旧程 ...

  5. spring boot + vue + element-ui全栈开发入门

    今天想弄弄element-ui  然后就在网上找了个例子 感觉还是可以用的  第一步是完成了  果断 拿过来  放到我这里这  下面直接是连接  点进去 就可以用啊 本想着不用vue   直接导入连接 ...

  6. 一个实际的案例介绍Spring Boot + Vue 前后端分离

    介绍 最近在工作中做个新项目,后端选用Spring Boot,前端选用Vue技术.众所周知现在开发都是前后端分离,本文就将介绍一种前后端分离方式. 常规的开发方式 采用Spring Boot 开发项目 ...

  7. 喜大普奔,两个开源的 Spring Boot + Vue 前后端分离项目可以在线体验了

    折腾了一周的域名备案昨天终于搞定了. 松哥第一时间想到赶紧把微人事和 V 部落部署上去,我知道很多小伙伴已经等不及了. 1. 也曾经上过线 其实这两个项目当时刚做好的时候,我就把它们部署到服务器上了, ...

  8. 部署spring boot + Vue遇到的坑(权限、刷新404、跨域、内存)

    部署spring boot + Vue遇到的坑(权限.刷新404.跨域.内存) 项目背景是采用前后端分离,前端使用vue,后端使用springboot. 工具 工欲善其事必先利其器,我们先找一个操作L ...

  9. 给大家整理了几个开源免费的 Spring Boot + Vue 学习资料

    最近抽空在整理前面的文章案例啥的,顺便把手上的几个 Spring Boot + Vue 的学习资料推荐给各位小伙伴.这些案例有知识点的讲解,也有项目实战,正在做这一块的小伙伴们可以收藏下. 案例学习 ...

随机推荐

  1. mysql数据库,当数据类型是float时,查询居然查询不出数据来

    mysql数据库,当数据类型是float时,查询居然查询不出数据来,类似如下: 以后mysql数据库不用float类型,而double类型可以查得出来.

  2. 经验:使用mysqlimport快速导入csv文件

    mysqlimport 工具实际上也只是"load data infile"命令的一个包装实现.常用选项:--fields-terminated-by=字符串:设置字符串为字段之间 ...

  3. centos7使用docker安装es(elasticsearch)

    1.安装docker依赖(已安装可以不用安装) yum install -y docker 2.搜索镜像 docker search elasticsearch 如果出现以下报错 Cannot con ...

  4. Hibernate 限制查询数目,使用limit功能

    在hql语句中,不能使用limit来限制显示的条数. 如果要限制查询的数目,要使用setMaxResults(e)方法来解决. query.setFirstResult(e);  //e是int值,要 ...

  5. 反解ios静态库

    p.p1 { margin: 0; font: 12px "Helvetica Neue" } p.p2 { margin: 0; font: 12px "Helveti ...

  6. 从源码角度解析 Springboot 2.6.2 的启动过程

    1. 概述 老话说的好:把简单的事情重复做,做到极致,你就成功了. 言归正传,Springboot的启动过程,一直都是面试的高频点,今天我们用当前最新的 Springboot 2.6.2 来聊一聊 S ...

  7. 【LeetCode】1461. 检查一个字符串是否包含所有长度为 K 的二进制子串 Check If a String Contains All Binary Codes of Size K

    作者: 负雪明烛 id: fuxuemingzhu 个人博客:http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 统计长度为 K 的子串个数 日期 题目地址:https ...

  8. 【九度OJ】题目1080:进制转换 解题报告

    [九度OJ]题目1080:进制转换 解题报告 标签(空格分隔): 九度OJ 原题地址:http://ac.jobdu.com/problem.php?pid=1080 题目描述: 将M进制的数X转换为 ...

  9. 【LeetCode】482. License Key Formatting 解题报告(Python)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 日期 题目地址:https://leetcode.c ...

  10. 【LeetCode】151. Reverse Words in a String 翻转字符串里的单词(Python)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客:http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 日期 题目地址:https://leetcode.co ...