后端代码:

@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. 当PowerDesigner的工具栏不见时候该怎么调出来

    当PowerDesigner的工具栏不见时候该怎么调出来,如下所示:选中[Palette]便可

  2. react 结合gitte 创建项目(详情步骤)

    ​ 创建项目第一步 基本搭建 在创建之前,需要有一个git 仓库,我们要把项目搭建到git 中 目录介绍 cd 到某个盘 mkdir workspace 创建workspace文件夹 cd works ...

  3. .Net Core 项目发布在IIS上 访问404 问题对应

    对策: 1.进入线程池画面,将当前程序的线程池设为"无托管代码"   2.修改配置文件 Web.config,加上配置   原因: 因为.NetCore 5.0 自带集成了Swag ...

  4. JavaWebServle执行流程解析

    Servlet Servlet 1.定义: 注:servlet版本2.5 Servlet是Java的一个类.既然是一个类.那必然要遵循一定的规范.如下所示. a.必须继承 javax.servlet. ...

  5. c++设计模式概述之适配器

    类写的不规范(应该屏蔽类的拷贝构造函数和运算符=).少写点代码,缩短篇幅,重在理解. 实际中可不要这样做. 类比生活中的手机,pad等电源适配器. 简单来讲: 将原本  不匹配  的两者  变的匹配  ...

  6. 【LeetCode】537. Complex Number Multiplication 解题报告(Python & C++)

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

  7. 【LeetCode】236. Lowest Common Ancestor of a Binary Tree 解题报告(Python)

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

  8. 【LeetCode】334. Increasing Triplet Subsequence 解题报告(Python)

    [LeetCode]334. Increasing Triplet Subsequence 解题报告(Python) 标签(空格分隔): LeetCode 题目地址:https://leetcode. ...

  9. (数据科学学习手札133)利用geopandas绘制拓扑着色地图

    本文示例代码及文件已上传至我的Github仓库https://github.com/CNFeffery/DataScienceStudyNotes 1 简介 我们在绘制某些地图时,为了凸显出每个独立的 ...

  10. 使用 DDL 语句分别创建仓库表、供应商表、产品表和入库表,并对其进行操作

    查看本章节 查看作业目录 需求说明: 使用 DDL 语句分别创建仓库表.供应商表.产品表和入库表 使用 DML 语句分别新增一条仓库表.供应商表.产品表和入库表记录 使用 DML 语句更新满足指定条件 ...