应用场景
该功能主要是通过读取文件流,处理blob流为浏览器识别地址并返回回调处理方法,来处理一些通用的post下载功能或者获取blob流地址进行其他操作的功能。
例如:pdf预览
解决方案
方案一
说明: 统一处理获取blob流地址与post形式下载功能结合为一个方法处理
- 引入filesBlobDeal处理方法
import { filesBlobDeal } from '@/utils/common';
复制代码
- 调用filesBlobDeal处理方法
let fileObj = {
reqType: '', // 接口请求类型:必传项,传入"POST"或者"GET"
fileName: '', // 文件名称:下载文件时必传,其他情况下可不传,若传时 ".pdf", ".png", ".zip" 等类型后缀需要拼接上:例如:'word测试文档' + ".pdf"
dealType: '', // 文件处理类型:必传项,传入下载文件:'downLoad' 或者 预览时处理blob流为浏览器识别的地址: 'blobUrl'
paramObj: {}, // 入参对象值:非必传项,根据业务场景处理
};
const hide = message.loading('下载中..', 0); // 处理加载提示:下载中.. 加载中.. 等,自己根据需要场景修改
filesBlobDeal(url, fileObj, (code, msg, blobUrl) => {
if (code == 200) {
if(msg){message.success(msg);};
// 下面处理回调成功后业务逻辑
} else if (code == 30001) {
message.info(msg);
} else {
message.error('请求异常!');
}
hide(); // 关闭加载提示
});
复制代码
- filesBlobDeal处理逻辑方法
/*
* 读取文件流,处理blob流为浏览器识别地址,返回回调处理方法
* 入参说明:url:接口请求地址, fileObj:文件对象说明, callback(code, msg,blobUrl):回调方法 :
* code 接口响应状态码:200 正常 其他(400,500等)30001:无权限异常(接口定义) :调用失败,msg: 异常信息, blobUrl:浏览器识别的blob地址
* let fileObj = {
reqType: '', // 接口请求类型:必传项,传入"POST"或者"GET"
fileName: '', // 文件名称:非必传项,下载文件时必传,其他情况下可不传,若传时 ".pdf", ".png", ".zip" 等类型后缀需要拼接上
dealType: '', // 文件处理类型:必传项,下载文件:'downLoad' 或者 预览时处理blob流为浏览器识别的地址: 'blobUrl'
paramObj: {}, // 入参对象值:非必传项,根据业务场景处理
};
*/
export function filesBlobDeal(url, fileObj, callback) {
getFilesBlob(url, fileObj, function (code, blob) {
let reader = new FileReader();
// 当读取操作完成时调用
reader.onload = function (event) {
let content = reader.result; // 读取完成后,获取文件流内容
const url = window.URL.createObjectURL(blob);
if(fileObj && fileObj.dealType && fileObj.dealType == 'downLoad'){ // 下载文件
let fileType = fileObj.fileName.slice(fileObj.fileName.lastIndexOf('.') + 1).toLowerCase();
if(fileType == 'pdf'){
if (content.indexOf('PDF') > -1) { // 如果文件是pdf类型关键字
const a = document.createElement("a");
a.href = url;
a.download = fileObj.fileName; // 文件名称
a.click();
window.URL.revokeObjectURL(url); // 浏览器会自动释放createObjectURL创建的对象
callback && callback(code, "下载完成!");
}else {
callback && callback(30001, "您无权下载该文件");
}
}else{
const a = document.createElement("a");
a.href = url;
a.download = fileObj.fileName; // 文件名称
a.click();
window.URL.revokeObjectURL(url); // 浏览器会自动释放createObjectURL创建的对象
callback && callback(code, "下载完成!");
}
}else{ // 预览时处理blob流为浏览器识别的地址
callback && callback(code,undefined,url);
}
};
reader.readAsText(blob); // 读取文本文件
});
}
// 获取文件的Blob值
function getFilesBlob(url, fileObj, callback) {
let xhr;
if (typeof XMLHttpRequest != 'undefined') {
xhr = new XMLHttpRequest();
} else {
xhr = new ActiveXObject('Microsoft.XMLHTTP');
};
xhr.open(fileObj.reqType, url, true);
xhr.responseType = "blob";
let paramsObjStr = '';
if(fileObj.paramObj){ // 请求参数
xhr.setRequestHeader("Content-Type", "application/json");
paramsObjStr = JSON.stringify(fileObj.paramObj);
}
xhr.onload = function () {
if (this.status == 200) {
if (callback) callback(200, this.response);
}
else {
if (callback) callback(this.status);
}
};
if(fileObj.paramObj){
xhr.send(paramsObjStr);
}else{
xhr.send();
};
}
/*
* 浏览器会自动释放createObjectURL创建的对象
*/
export function releaseBlobUrl(url) {
window.URL.revokeObjectURL(url);
}
复制代码
方案二
说明: 获取文件blob流地址与post形式下载功能拆分为单个方法处理(推荐使用)
- 引入downloadFiles处理方法
import {downloadFiles } from '@/utils/common';
复制代码
- 调用downloadFiles处理方法
- 简单的window自动下载: 只需要传入拼接好参数的下载地址就行
downloadFiles(url); // 例如:'/**/**/download?id=120'
复制代码
- 通过post方式获取文件blob流下载
let fileObj = {
reqType: '', // 接口请求类型:必传项,传入"POST"或者"GET"
fileName: '', // 文件名称:必传项,".pdf", ".png", ".zip" 等类型后缀需要拼接上
paramObj: {}, // 入参对象值:非必传项,根据业务场景处理
};
const hide = message.loading('下载中..', 0); // 处理加载提示:下载中..
downloadFiles(url, fileObj, (code, msg) => {
if (code == 200) {
if(msg){message.success(msg);};
} else if (code == 30001) {
message.info(msg);
} else {
message.error('下载异常!');
}
hide(); // 关闭加载提示
});
复制代码
- downloadFiles处理方法:
/*
* 通用型下载方法:包含直接下载及读取文件流,处理blob流为浏览器识别地址,进行下载
* 入参说明:url:接口请求地址, fileObj:文件对象说明, callback(code, msg):回调方法
* code 接口响应状态码:200 正常 其他(400,500等)30001:无权限异常(接口定义) :调用失败,msg: 异常信息
* let fileObj = {
reqType: '', // 接口请求类型:必传项,传入"POST"或者"GET"
fileName: '', // 文件名称:必传项,".pdf", ".png", ".zip" 等类型后缀需要拼接上
paramObj: {}, // 入参对象值:非必传项,根据业务场景处理
};
*/
export function downloadFiles(url, fileObj, callback) {
if(fileObj){
getFilesBlob(url, fileObj, function (code, blob) {
let reader = new FileReader();
// 当读取操作完成时调用
reader.onload = function (event) {
let content = reader.result; // 读取完成后,获取文件流内容
const url = window.URL.createObjectURL(blob);
let fileType = fileObj.fileName.slice(fileObj.fileName.lastIndexOf('.') + 1).toLowerCase();
if(fileType == 'pdf'){
if (content.indexOf('PDF') > -1) { // 如果文件是pdf类型关键字
const a = document.createElement("a");
a.href = url;
a.download = fileObj.fileName; // 文件名称
a.click();
window.URL.revokeObjectURL(url); // 浏览器会自动释放createObjectURL创建的对象
callback && callback(code, "下载完成!");
}else {
callback && callback(30001, "您无权下载该文件");
}
}else{
const a = document.createElement("a");
a.href = url;
a.download = fileObj.fileName; // 文件名称
a.click();
window.URL.revokeObjectURL(url); // 浏览器会自动释放createObjectURL创建的对象
callback && callback(code, "下载完成!");
}
};
reader.readAsText(blob); // 读取文本文件
});
}else{
window.location.href = url; // 仅传url地址时(无fileObj, callback参数),默认为处理为window自动下载
}
}
复制代码
- 获取文件blob流地址
- 引入getFilesBlobUrl处理方法
import {getFilesBlobUrl } from '@/utils/common';
复制代码
- 调用getFilesBlobUrl处理方法
let fileObj = {
url: '', // 接口请求地址
paramObj: {}, // 入参对象值:非必传项,根据业务场景处理
};
const hide = message.loading('文件读取中..', 0); // 处理加载提示:下载中.. 加载中.. 等,自己根据需要场景修改
getFilesBlobUrl(fileObj, (code, blobUrl) => {
if (code == 200) {
// 下面处理回调成功后业务逻辑
} else {
message.error('请求异常!');
}
hide(); // 关闭加载提示
});
复制代码
- getFilesBlobUrl 处理方法
/*
* 获取文件blob地址:读取文件流,处理blob流为浏览器识别地址,返回回调处理方法
* 入参说明:fileObj:文件对象说明, callback(code, blobUrl):回调方法 :
* code 接口响应状态码:200 正常 其他(400,500等),blobUrl:浏览器识别的blob地址
* let fileObj = {
url: '', // 接口请求地址
paramObj: {}, // 入参对象值:非必传项,根据业务场景处理
};
*/
export function getFilesBlobUrl(fileObj, callback) {
fileObj.reqType = 'POST'; // 默认只处理post格式
getFilesBlob(fileObj.url, fileObj, function (code, blob) {
let reader = new FileReader();
// 当读取操作完成时调用
reader.onload = function (event) {
const url = window.URL.createObjectURL(blob);
callback && callback(code,url); // 预览时处理blob流为浏览器识别的地址
};
reader.readAsText(blob); // 读取文本文件
});
}
复制代码
- 使用完成创建的blob流,需要及时销毁释放资源: 调用releaseBlobUrl处理方法
import {releaseBlobUrl } from '@/utils/common';
releaseBlobUrl(url); // url:需要释放的地址,即刚才获取到的blobUrl
复制代码