一、ajax请求获取二进制流文件解决办法
今天在做excel导出的时候,碰到了一系列问题,以下是记录。
首先,整个过程就是现在前台页面先封装好要下载的文件数据,然后点击按钮触发了ajax请求,然后后台php就进行了数据的获取,处理数据,然后引用php的插件Spreadsheet生成了对应的图表,然后直接对着前台输出了:
以下为后台php代码向前端输出的文件流
header(‘filename:’.$file_name);
//没有缓存
header(‘Cache-Control:no-cache,no-store’);
//允许获取的访问头部
header(‘Access-Control-Expose-Headers:filename’);
w
r
i
t
e
r
=
I
O
F
a
c
t
o
r
y
:
:
c
r
e
a
t
e
W
r
i
t
e
r
(
writer = IOFactory::createWriter(
writer=IOFactory::createWriter(spreadsheet, ‘Xlsx’);
$writer->save(‘php://output’);
以上就是tp5后端控制器方法的结束,那么问题来了
以上返回的报文中,所储存的是二进制流文件。然后用惯了jq的ajax的我,就懵逼了,一直以为数据交流只有html,text,json,xml,然后查了资料后发现原来还有blob这种数据交流。
然后就用了纯js去获取数据,然后得到数据后
以下是整个前端获取数据流并下载的流程(重点)
var url=server_url+'/index/index/get_rep'; //请求的URl
var xhr = new XMLHttpRequest(); //定义http请求对象
xhr.open("POST", url, true);
xhr.setRequestHeader("Content-type","application/x-www-form-urlencoded");
xhr.send("userId="+username+"&password="+password+"&repo_type="+type+"&repo_time=");
xhr.responseType = "blob"; // 返回类型blob
xhr.onload = function() { // 定义请求完成的处理函数,请求前也可以增加加载框/禁用下载按钮逻辑
if (this.status===200) {
var blob = this.response;
var reader = new FileReader();
reader.readAsDataURL(blob); // 转换为base64,可以直接放入a表情href
reader.onload=function (e) {
console.log(e); //查看有没有接收到数据流
// 转换完成,创建一个a标签用于下载
var a = document.createElement('a');
a.download="data_repo"+".xlsx"; //自定义下载文件名称
a.href = e.target.result;
$("body").append(a); // 修复firefox中无法触发click
a.click();
$(a).remove();
}
}
else{
alert("出现了未知的错误!");
}
}
上面就是整个前后台blob数据流文件交流, (下面为片段解释) :
var reader = new FileReader();
reader.readAsDataURL(blob);
这种方式读取文件完之后,又使用了
reader.onload=function (e) {
console.log(e);
// 转换完成,创建一个a标签用于下载
var a = document.createElement('a');
a.download="data_repo"+".xlsx"; //自定义下载文件名称
a.href = e.target.result;
$("body").append(a); // 修复firefox中无法触发click
a.click();
$(a).remove();
}
这种方式来下载读取完的目标文件,然后用a链接下载下来
分割线
分享个vue学习的教程
本人亲自维护的接口
非常适合vue零基础或者刚入门vue的小白学习。
资源包括源码、视频、接口文档,从入门到实战项目
如果你想学习vue,这里有个项目线上尝鲜地址:http://129.226.76.172:5325