通过ajax请求后端生成的文件流之后,创建BLOB文件进行下载,在PC端和移动安卓端都可以实现下载到本地
步骤
通过request,responseType的值为 'arraybuffer',请求对应的文件流
uni.request({
...handleRes,
responseType: 'arraybuffer',
success(res) {
// console.log(res, '返回数据');
// 这是返回的文件流
const file = res.data;
},
fail() {
uni.hideLoading();
}
})
通过将文件流转成blob对象
let blob = null;
if (headerDis.indexOf(tyepList.toString()) != -1) {
blob = new Blob([file], {
type: 'application/octet-stream;charset=UTF-8',
})
} else {
blob = new Blob([file], {
type: headerInfo['content-type'] ||
'application/octet-stream;charset=UTF-8',
})
}
通过创建A链接,通过download属性进行下载
async linkTodownloadFile(blob, fName) {
if (window.navigator.msSaveOrOpenBlob) {
window.navigator.msSaveBlob(blob, fName);
return false;
}
const url = window.URL.createObjectURL(blob)
const link = document.createElement('a')
link.style.display = 'none'
link.href = url;
link.setAttribute('download', fName)
document.body.appendChild(link)
if (document.all) {
link.click();
} else {
// 兼容 Firfox
const evt = document.createEvent('MouseEvents');
evt.initEvent('click', true, true);
link.dispatchEvent(evt);
}
document.body.removeChild(link) // 下载完成移除元素
window.URL.revokeObjectURL(url);
}
demo
uni.request({
url : 'xxx',
responseType: 'arraybuffer',
success(res) {
// console.log(res, '返回数据');
const file = res.data;
const headerInfo = res.header;
/** 获取文件名称 */
let fName = '';
/** 判断是否为可自定义类型还是默认 */
const tyepList = ['pdf'];
const headerDis = headerInfo['content-disposition'];
if (headerDis) {
const requestFileInfo = headerDis.split(';')[1];
if (store.state.app.SYSTEM_INFO.platform == 'ios') {
if (headerDis.indexOf(tyepList.toString()) != -1) {
fName = requestFileInfo;
} else {
fName = requestFileInfo.split('.')[0];
}
} else {
fName = requestFileInfo;
}
} else {
/** 判断文件是否有类型,没有就拿效应头 */
const fType = file.type || headerInfo['content-type'].split(';')[0];
for (const key in fileTypeConfig) {
if (fileTypeConfig[key].indexOf(fType) != -1) {
if (store.state.app.SYSTEM_INFO.platform == 'ios') {
fName = `${fileName}`;
} else {
fName = `${fileName}.${key}`;
}
break
}
}
}
/** 开始下载 */
let blob = null;
if (headerDis.indexOf(tyepList.toString()) != -1) {
blob = new Blob([file], {
type: 'application/octet-stream;charset=UTF-8',
})
} else {
blob = new Blob([file], {
type: headerInfo['content-type'] ||
'application/octet-stream;charset=UTF-8',
})
}
/** 判断是否为JSON 做逻辑处理 */
if (fName.indexOf('json') != -1) {
//通过FileReader读取数据
const reader = new FileReader();
// reader.readAsBinaryString(blob);
reader.readAsText(blob, 'utf8');
reader.onload = function() {
var content = JSON.parse(this.result); //这个就是解析出来的数据
if (content.code == 200) {
that.linkTodownloadFile(blob, fName);
resolve();
} else {
isLoading && uni.hideLoading();
common.toast(content.msg || 400);
}
}
} else {
that.linkTodownloadFile(blob, fName);
resolve();
}
},
fail() {
reject();
}
})
下载文件分类
链接下载
// 调用api示例,返回一个url
await url= await Api.getDownloadUrl({
data: { something }
});
function jsDownload(url){
// 生成一个a标签
var a = document.createElement('a');
document.body.appendChild(a);
// 如果是完整的链接
a.href = url;
// 如果只是返回了后半段的链接
// a.href = location.origin + url;
// 静态文件的话不一定会生效,所以后端要把名字起好
a.download = '文件名'+'.xls';
// 触发点击
a.click();
// 用完就删掉,避免越加越多
document.body.removeChild(a);
}
jsDownload(url);
二进制流下载
需要设置 responseType: ‘blob’
// 以 axios为例,其它的插件也差不多,这里主要讲收到之后怎么处理
axios.get(url,{
responseType:'blob',
}).then(res => {
downloadFile(res.data)
})
// 转化为blob对象下载
function downloadFile(data){
const blob = new Bolb([data], {type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8'})
// 把blob对象转成一个可下载的链接;注意:window.URL或者URL都行
let url = URL.createObjectURL(blob);
jsDownload(url);
// 下载完记得删掉链接,延时更保险;4E4就是40秒
setTimeout(function () { URL.revokeObjectURL(url) }, 4E4)
}
为什么下载文件加FileReader
FileReader是js读取文件的API,在下载文件使用的时候,作用跟URL.createObjectURL是一样的,都是为了生成a标签能下载的链接,但是它跟URL.createObjectURL的区别就是,URL.createObjectURL苹果不兼容
// 下面的代码只是示意,要做兼容用后面介绍的file-saver.js
var reader = new FileReader()
reader.onloadend = function () {
var url = reader.result
url = isChromeIOS ? url : url.replace(/^data:[^;]*;/, 'data:attachment/file;')
jsDownload(url)
}
reader.readAsDataURL(blob)
使用file-saver.js
npm install file-saver --save
# 如使用TS开发,可安装file-saver的TypeScript类型定义
npm install @types/file-saver --save-dev
import FileSaver from 'file-saver';
FileSaver saveAs(Blob/File/Url,fileType)
// 参数1:支持的类型:blob(二进制)、File(文件)、Url(url链接)
// 参数2:文件类型
保存文本
// 保存文本
saveText() {
// 创建二进制文件
let blob = new Blob(['保存一个文本'],{type: 'text/plain;charset=utf-8'});
FileSaver.saveAs(blob,'a.txt');
}
保存url
saveUrl() {
FileSaver.saveAs('https://ppt.1ppt.com/uploads/soft/2202/1-2202231A334.zip', 'a.zip');
}
保存canvas
var canvas = document.getElementById("my-canvas");
canvas.toBlob(function(blob) {
FileSaver.saveAs(blob, "pretty image.png");
});
保存文件
saveFile() {
let file = new File(['保存一个文件'],'a.txt',{type: 'text/plain;charset=utf-8'});
FileSaver.saveAs(file);
}