我很久之前写了一篇前端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. asp.net core监控—引入Prometheus(三)

    上一篇博文中说到Prometheus有四种指标类型:Counter(计数器).Gauge(仪表盘).Histogram(直方图).Summary(摘要),并且我们做了一个Counter的Demo,接下 ...

  2. Homework_3 (完整版)

    划水‍♂️!好耶! 果然还是逃不过作业,初三刚过就要营业 审题 爬虫+算法:划水中的员工 员工 A 此刻内心一酸,大年初一加班惨绝人寰,情不自禁打开 B 站,跟着网友一起划水看番. 但是由于技术故障原 ...

  3. WebAssembly环境搭建

    Environment:Ubuntu 16.06 + emscripten URL: https://emscripten.org/docs/getting_started/downloads.htm ...

  4. uni微信小程序优化,多个分包在用的公共代码该放在哪?

    公共的代码包括公用的vue组件和js代码,从维护性的角度来说应该放到主包才对, 但是主包有大小限制,如果把2个分包都在用的代码放到主包里面那2M很快就满了. 所以该放在哪?我的方案是从维护的角度放在主 ...

  5. AT5801 [AGC043D] Merge Triplets

    这种排列生成排列的题目我们一般可以考虑生成排列合法的充要条件. 首先可以发现的一点就是该生成排列的任意一个数 \(p_i\) 一定不存在连续的三个数 \(p_{i + 1}, p_{i + 2}, p ...

  6. AT2043 [AGC004C] AND Grid

    首先可以发现一个很简单的想法,因为最外层是一定不会有 \(\#\) 的,所以可以考虑让第一个网格图将每个连通块的最外层包起来,第二个网格图将就选择这个包内部的所有点即可. 但你发现这个想法是很难实现的 ...

  7. ApacheJemeter的简单使用

    前言:最近由于工作需要进行接口测试,故简单复习一下ApacheJemeter的使用 安装包下载地址: 链接:https://pan.baidu.com/s/11ywNWRUkFNNBCWw4HiO6B ...

  8. Android下数据库创建

    什么情况下我们才用数据库做数据存储? 大量数据结构相同的数据需要存储时. sqlite 嵌入式 轻量级 SqliteOpenHelper 创建数据库步骤: 1.创建一个类集成SqliteOpenHel ...

  9. npm 查看一个包的版本信息

    有了npm 我们能够简单的一段代码就下载我们需要的包,但是包是不断更新的, 所以我们要关注包的版本信息: 现在,假设我们需要 jquery ,但是jquery现在有很多版本,我们如何通过npm查看呢? ...

  10. 全局定义UINavigationContoller--By秀清

    // // NavController.m // // Created by Joe Zhang on 15/5/23. // Copyright (c) 2015年 张秀清. All rights ...