后端代码:

@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. java判断一个字符串是否为数字(整型、int)

    引入commons-lang 的jar包 /** * 判断是否是数字类型 * @param str * @return 如果为空返回false 匹配返回true */ public static bo ...

  2. 【LeetCode】983. 最低票价 Minimum Cost For Tickets(C++ & Python)

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

  3. 【剑指Offer】旋转数组中的最小数字 解题报告(Python)

    [剑指Offer]旋转数组中的最小数字 解题报告(Python) 标签(空格分隔): LeetCode 题目地址:https://www.nowcoder.com/ta/coding-intervie ...

  4. 【LeetCode】781. Rabbits in Forest 解题报告(Python & C++)

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

  5. See you~(hdu1892)

    See you~ Time Limit: 5000/3000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others)Total Su ...

  6. Nginx 简单配置反向代理

    nginx 配置反向代理,转发请求到另一个域名 在server中加入 location /${alias} { proxy_buffer_size 128k; proxy_buffers 32 32k ...

  7. Scalable Rule-Based Representation Learning for Interpretable Classification

    目录 概 主要内容 Wang Z., Zhang W., Liu N. and Wang J. Scalable rule-based representation learning for inte ...

  8. Dapper in .Net Core

    一.前言 关于什么是Dapper,在此不做赘述:本文仅对Dapper在.Net Core中的使用作扼要说明,所陈代码以示例讲解为主,乃抛砖引玉,开发者可根据自身需要进行扩展和调整:其中如有疏漏之处,望 ...

  9. Java初学者作业——分别计算两个整数加、减、乘、除的结果并显示,要求除法保留两位小数。

    返回本章节 返回作业目录 需求说明: 分别计算两个整数加.减.乘.除的结果并显示,要求除法保留两位小数. 实现思路: 接收用户控制台输入的两个整数. 实现两个整数的加.减.乘.除的运算并输出结果. 除 ...

  10. Java基础周测一、二(50题)

    一.单选题 (共50题,250分) 1.下列选项不可作为Java语言变量名的是(    ). A. a1 B. $1 C. _1 D. 21 正确答案: D 2.有一段Java应用程序,它的类名是a1 ...