导出文件请求返回JSON数据和文件流数据处理办法(返回二进制乱码可处理)
json
适用于现代 C++ 的 JSON。
项目地址:https://gitcode.com/gh_mirrors/js/json
免费下载资源
·
背景:在新窝点学习,需求是导出表格(固定,其它文件类型这里不涉及),但后端最大导出量是20W,超过20W查询就返回JSON格式数据,如{“code”: “xxx”, “msg”:“超过20W,导出失败”, xxxx},所以需要前端去做导出数据的处理,废话也不多说,走流程:
一、我们需要处理封装的请求:
ps:我这里使用flyio,也验证过了axios
// 给请求加responseType属性,具体可以查看mdn,
// 看字面意思你可理解为加了此属性可使得响应返回的类型是XXX,
// 因为文件类型,所以需要加blob或者arrayBuffer处理二进制数据
// 可查看文档确认responseType是和url,body等同级,封装下,加上即可
let req = {
// ...
url: url, // 忽略
body: body, // 忽略
responseType: 'blob' || '' //只关注这里:blob或者arrayBuffer
// ...
}
// 导出封装,只需要调用方法加接口地址
export function getExport(url) {
return httpRquest({ url, method: 'GET', responseType: 'arraybuffer' })
}
ps:可了解下Blob和 ArrayBuffer,参考MDN:
Blob
https://developer.mozilla.org/zh-CN/docs/Web/API/Blob
ArrayBuffer
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/ArrayBuffer
二、返回数据处理:
ps:这里$api内是已经添加接口地址的类,直接调用即可,个人自定义就好,这里只是范例:
- responseType为blob
相关代码:
this.$api.xxx().then((res) => {
console.log(res); // Blob对象 { size: 1234, type: "xxxxxx"}
// Blob对象根据mdn描述,如果能解析,type是有值的,不然为空字符串
// 这里返回是表格文件和JSON数据
// 因此type会为:
// 文件:application/octet-stream
// JSON数据:application/json
// 进行简单判断为blob对象:
if(res && res.type) {
let type = res.type;
if(type === "application/octet-stream") {
// Blob 对象处理
let blob = new Blob([res], { type: "application/octet-stream" });
// 下方代码有处理导出的文件的代码
return;
}
if(type === "application/json") {
// json 数据处理
let reader = new FileReader();
reader.onload = (data) => {
// data是个对象 {..., target: { ..., result: 'asda', ....}}
// 会有一个target属性里包含了返回的JSON
if (data.target && data.target.result) {
let result = data.target.result;
// 进行自定义校验
if (
typeof result === "string" &&
result.includes("code") &&
result.includes("msg")
) {
result = JSON.parse(data.target.result);
// 自定义处理
return;
}
}
};
reader.error= (err)=> {
// 读取失败,自定义处理
console.log(err)
}
// 数据解析为json,理解为读取文件数据
reader.readAsText(new Blob([res], { type: "application/json" }));
return;
}
}
// 没有这里直接就算失败吧,根据实际情况自定义
console.log('导出失败')
}.catch((err) => {
console.log('导出失败')
});
导出下载文件相关代码:
// 此处是拿生成blob类型数据进行表格下载,这个网上一大片,因为项目不兼容低版本ie,所以对此需要更优化的自行百度或者google更好的哦!
let aLink = document.createElement("a");
aLink.addEventListener("click", (e) => {
aLink.download = `表格名称.xls`;
aLink.href = URL.createObjectURL(blob);
});
let e = document.createEvent("MouseEvents");
e.initEvent("click", false, false);
aLink.dispatchEvent(e);
- responseType为arrayBuffer
this.$api.xxx().then((res) => {
console.log(res); // arrayBuffer数据
// Blob对象根据mdn描述,如果能解析,type是有值的,不然为空字符串
// 这里返回是表格文件和JSON数据
// 文件:application/octet-stream
// JSON数据:application/json
var reader = new FileReader();
reader.onload = (data) => {
// 是错误信息返回
if (data.target && data.target.result) {
let result = data.target.result;
if (
typeof result === "string" &&
result.includes("code") &&
result.includes("msg")
) {
result = JSON.parse(data.target.result);
this.$message.error(result.msg);
return;
}
}
// 是文件
let blob = new Blob([res], { type: "application/octet-stream" });
// 上方代码有处理导出的文件的代码
}
}
reader.readAsText(new Blob([res], { type: "application/json" })); // 按照json解析
}.catch((err) => {
console.log('导出失败')
});
三、最后:
个人建议能使用proxy/await就用,进行try catch错误拦截,然后做一些错误处理,看到我进行很多的判断也是因为确保数据存在,可能多余,但实际这样做也没问题。
实际会有人觉得返回是乱码,但那其实就是文件二进制流,使用blob或arrayBuffer处理即可。
最后的最后,希望能帮到解决业务问题!
GitHub 加速计划 / js / json
41.72 K
6.61 K
下载
适用于现代 C++ 的 JSON。
最近提交(Master分支:1 个月前 )
960b763e
3 个月前
8c391e04
6 个月前
更多推荐
已为社区贡献3条内容
所有评论(0)