我很久之前写了一篇前端vue利用blob对象下载文件,有些人私信我,如果后端返回流失败,给出的json对象该怎么获得?前端获取的流怎么能获取原文件名?其实在那篇文章之后,我就已经针对这两个问题进行了优化,于是就有了这篇。

  首先,针对第一个问题,如果能正常获得文件流,前端则以blob对象承接,反之,一般后端会传一个json对象告诉你失败了以及失败原因,这个时候json对象由于请求中responseType: 'blob'的声明之后,也会生成文件,但是文件内容是乱码,这个时候,我们必须要用到FileReader.readAsText():

详细见MDN官方文档关于FileReader.readAsText()的描述:https://developer.mozilla.org/zh-CN/docs/Web/API/FileReader/readAsText。所以上次的代码经过改造是这样子的:

<el-button @click="exportExcel()">导出</el-button>

<script>
methods: {
exportExcel(){
var params={
XX:xx//额外需要携带的请求体
}
this.$axios.get('/XX/XX',{
params: params,
responseType: 'blob' //首先设置responseType字段格式为 blob
}).then(res => {
if(res.type=="application/json"){
let reader = new FileReader();
reader.onload = e =>this.$alert(JSON.parse(e.target.result).xxxx); //xxxx为字段名
reader.readerAsText(res);
}else{
let blob = new Blob([res], {type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=UTF-8"}); // 为blob设置文件类型,这里以.xlsx为例
let url = window.URL.createObjectURL(blob); // 创建一个临时的url指向blob对象
let a = document.createElement("a");
a.href = url;
a.click();
// 释放这个临时的对象url
window.URL.revokeObjectURL(url);
}
});
},
}
</script>

  然后,我们针对第二个问题,前端获取的流怎么能获取原文件名?有两种解决方案,都得需要后端同事的配合,一种是在点击导出按钮之前,一般这种就是有一个文件列表(表格),前端已经知道文件的位置,然后把文件路径传给后端,由后端到指定目录下取到再传给你。文件上传的时候因为防止文件名重复,后端会对文件进行重命名(采取8位随机字符串+原文件名),在你知道路径的情况下,你就可以直接将文件路径中最后一个"/"后字段进行截取作为文件名。 

<el-button @click="exportExcel()">导出</el-button>

<script>
methods: {
exportExcel(){
var params={
filePath:this.filePath
}
this.$axios.get('/XX/XX',{
params: params,
responseType: 'blob' //首先设置responseType字段格式为 blob
}).then(res => {
if(res.type=="application/json"){
let reader = new FileReader();
reader.onload = e =>this.$alert(JSON.parse(e.target.result).xxxx); //xxxx为字段名
reader.readerAsText(res);
}else{
let blob = new Blob([res], {type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=UTF-8"}); // 为blob设置文件类型,这里以.xlsx为例
let url = window.URL.createObjectURL(blob); // 创建一个临时的url指向blob对象
let a = document.createElement("a");
a.href = url;
let filePath = this.filePath;
let subFilePath = filePath.split('/');
a.download = subFilePath[subFilePath.length-1].substring(8);
a.click();
// 释放这个临时的对象url
window.URL.revokeObjectURL(url);
}
});
},
}
</script>

  另一种是后端同事先对请求头进行改造,在给前端返回的请求头中添加Content-Dispositon字段。

response.reset();
response.setContentType("application/application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=UTF-8"); //设置文件类型,这里以.xlsx为例
//设置文件的原文件名,若文件名中含有中文则需要解码,否则会出现乱码
response.setHeader("Content-Disposition", "attachment;fileName=" + URLEncoder.encode(fileName, "utf-8"));
// 这步很关键,需要在给前端返回的请求头中添加Content-Disposition字段
response.setHeader("Access-Control-Expose-Headers", "Content-Disposition");  

f12控制台network中请求头部分

  然后有些人就是在这个地方卡住了,说利用res.headers['content-disposition']取不到Content-Dispositon的值,这是因为这些人都配置了axios拦截器,而且在拦截器里写了相关的处理导致没有返回全部的响应信息。我们在上面代码中.then()回调函数中的res返回前是都要经过axios拦截器处理的,如果没有设置axios拦截器的是可以直接通过res.headers['content-disposition']直接获取到的。

// 添加响应拦截器
axios.interceptors.response.use(response=>{
// 对响应数据做点什么
return response.data; //这里只把这个响应里的data返回回来了,所以取不到headers,想要全部信息就return response;
}, error=>{
// 对响应错误做点什么
return Promise.reject(error);
});

前端vue下载文件时blob返回流中怎么获取文件名的更多相关文章

  1. 使用HttpURLConnection下载文件时出现 java.io.FileNotFoundException彻底解决办法

    使用HttpURLConnection下载文件时经常会出现 java.io.FileNotFoundException文件找不到异常,下面介绍下解决办法 首先设置tomcat对get数据的编码:con ...

  2. 下载文件时-修改文件名字 Redis在Windows中安装方法 SVN安装和使用(简单版) WinForm-SQL查询避免UI卡死 Asp.Net MVC Https设置

    下载文件时-修改文件名字   1后台代码 /// <summary> /// 文件下载2 /// </summary> /// <param name="Fil ...

  3. 转载: 正确处理浏览器在下载文件时HTTP头的编码问题(Content-Disposition)

    最近在做一个下载工具时,发现CSDN上的资源下载时竟然没有被拦截到,经过分析,终于有了一个发现,解决了我之前做文件下载时的乱码问题,所以转载这篇释疑文章,希望有人可以看到,可以从中得到帮助,也用来备忘 ...

  4. Firefox下载文件时中文名乱码问题

    为了形象化,先看几张不同浏览器下下载文件时的效果图: 1:Firefox 36.0.1 2:IE8 3:Chrome 40.0.2214.93 m 4:360 7.1.1.322 很明显在Firefo ...

  5. 正确处理下载文件时HTTP头的编码问题(Content-Disposition)

    留坑 参考: 正确处理下载文件时HTTP头的编码问题(Content-Disposition) HTTP协议header中Content-Disposition中文文件名乱码 文件下载,content ...

  6. C#中解决Response.AddHeader("Content-Disposition", "attachment; filename=" + filename)下载文件时文件名乱码的问题

    问题:下载文件时文件名乱码怎么解决? 在C#写后台代码过程中,经常遇到下载文件出现文件名乱码的问题,在网上找了很多方法,总是存在浏览器不兼容的问题,当IE浏览器不乱码时,火狐浏览器就会乱码,后来经过反 ...

  7. java下载文件时文件名出现乱码的解决办法

    转: java下载文件时文件名出现乱码的解决办法 2018年01月12日 15:43:32 橙子橙 阅读数:6249   java下载文件时文件名出现乱码的解决办法: String userAgent ...

  8. 在Xshell中上传下载文件到本地(linux中从多次ssh登录的dbserver里面的文件夹)

    在Xshell中上传下载文件到本地(linux中从多次ssh登录的dbserver里面的文件夹) 1 列出所有需要copy的sh文件 -bash-4.1$ ll /mysqllog/osw/*.sh ...

  9. .net WebApi 批量文件进行压缩zip以二进制流传输至前端(Vue)下载

    前言:最近接了个项目,需要进行将服务端生成的文件进行打包压缩供前端下载,百度查了下资料,决定采用SharpZipLib C#开园的压缩解压库进行服务器文件压缩,在实现过程,郁闷的是前端接收下载下来的压 ...

随机推荐

  1. python整数运算--4

    #!/usr/bin/python #coding=utf-8 i=1 j=3 print(i*j) print(i**j)

  2. 近期Android学习

    近5天没有更新博客,因为这几天略微放下了python的学习,android这边连带项目比较急迫,先花大约1个星期的时间把重心放在Android,但python肯定还会坚持下去,毕竟连着学了那么久了. ...

  3. %r和%s的区别

    理解%r和%s的区别 %r会重现所表达的对象,%s会将所有转成字符串 eg1: print('i am %s years old' % 22) print('i am %r years old' % ...

  4. mybatis 接口中定义方法、映射文件、实体类之间的关系?

    一.定义实体类 ,注意需求 是一对多还是多对一.  这里用员工和部门  多对一的关系举例. package com.zs.entity; /* * /* * 多对一? * 多个员工 对应一个部门 一个 ...

  5. ApacheCN PHP 译文集 20211101 更新

    PHP 入门指南 零.序言 一.PHP 入门 二.数组和循环 三.函数和类 四.数据操作 五.构建 PHP Web 应用 六.搭建 PHP 框架 七.认证与用户管理 八.建立联系人管理系统 使用 PH ...

  6. Git .gitignore 不起作用的解决办法

    解决方法的原理:.gitignore只能忽略那些原来没有被track的文件,如果某些文件已经被纳入了版本管理中,则修改.gitignore是无效的. 解决方案:git rm -r --cached . ...

  7. 原生js获取子元素

    感谢原文作者:归一山人 原文链接:https://www.cnblogs.com/guiyishanren/p/12214757.html 获取子元素的方法有 //获取第一个demo类 dom = d ...

  8. Shell编程中的用户输入处理

    Linux read命令用于从标准输入读取数值. read 内部命令被用来从标准输入读取单行数据.这个命令可以用来读取键盘输入,当使用重定向的时候,可以读取文件中的一行数据. 语法 read [-er ...

  9. 异步回调实现- Guava Retryer

    为什么要使用重试利器Retryer 在实际开发中我们经常会遇到需要轮询查询一个接果,实现轮询的方式有很多种,我们经常要写许多代码,有时还会怕写出的代码有bug,如果已经有轮子了,我们就没必要重复造轮子 ...

  10. js图片预览代码

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...