前端文件操作
以下将介绍自定义对文件进行操作的一些注意点
前端读取使用文件一般需要对 File 进行处理,下列是处理的方式
reader.readAsDataURL(f); // 将 Blob 或 File 读取为 data:URL格式的字符串(base64编码)
reader.readAsBinaryString(f); // 将 Blob 或 File 读取为文件原始二进制格式
reader.readAsArrayBuffer(f); // 将 Blob 或 File 读取为 ArrayBuffer 对象
reader.readAsText(f); // 将 Blob 或 File 读取为内容(字符串形式)
笔者是拖拽获取到的File ,代码如下
js
this.$refs.dragArea.ondrop = (e) => {
e.dataTransfer.files[0] // 拖拽的一个文件
}前端使用上传接口一般要传递FormData对象,此时content-type应为multipart/form-data(笔者未进行配置浏览器便自动识别为multipart/form-data),手动配置大致如下
js
// 发票上传
export function apiPostUpload(data) {
return request({
url: portalPrefix + '/wallet/upload',
method: 'post',
headers:{'Content-Type':'multipart/form-data'}, // 这里设置了
data
});
}值得注意的multipart/form-data这种方法传递的date需要是FormData类
js
const formData = new FormData();
formData.append('userid', this.$store.state.user.userInfo.nsrid);
formData.append('utype', 1);
formData.append('file', this.file);
const res = await apiPostUpload(formData);前端下载文件
文件流直接window.open(),base64可以用一下方法进行解析(转为blob并创建可下载的url)
js
/**
* @author sqm
* @description 将blob转回文件并下载
* @param {String} base64Url 要下载的base64
* @backDes
*/
const downloadBase64 = (base64Url, downloadName = 'download') => {
// 获取后缀
let arr = base64Url.split(','), mime = arr[0].match(/:(.*?);/)[1];
let suffix = arr[0].match(/\/(.*);/)[1];
if('msSaveOrOpenBlob' in navigator){
//ie使用的下载方式
base64Url = base64Url.replace(/[\n]/g,""); // 去除换行符
// 截取base64的数据内容(去掉前面的描述信息,类似这样的一段:data:image/png;base64,)并解码为2进制数据
var bstr = atob(base64Url.split(',')[1]);
// 获取解码后的二进制数据的长度,用于后面创建二进制数据容器
var n = bstr.length;
// 创建一个Uint8Array类型的数组以存放二进制数据
var u8arr = new Uint8Array(n);
// 将二进制数据存入Uint8Array类型的数组中
while (n--) {
u8arr[n] = bstr.charCodeAt(n);
}
// 创建blob对象
var blob = new Blob([u8arr]);
// 调用浏览器的方法,调起IE的下载流程
window.navigator.msSaveOrOpenBlob(blob, `${downloadName}.${suffix || 'pdf'}`);
} else{
// 非ie下载
function dataURLtoBlob(dataurl) {
var arr = dataurl.split(','), mime = arr[0].match(/:(.*?);/)[1],
bstr = atob(arr[1]), n = bstr.length, u8arr = new Uint8Array(n);
while (n--) {
u8arr[n] = bstr.charCodeAt(n);
}
return new Blob([u8arr], { type: mime });
}
function downloadFile(url,name='download'){
var a = document.createElement("a");
a.setAttribute("href",url);
a.setAttribute("download",name);
a.setAttribute("target","_blank");
let clickEvent = document.createEvent("MouseEvents");
clickEvent.initEvent("click", true, true);
a.dispatchEvent(clickEvent);
}
function downloadFileByBase64(base64,name){
var myBlob = dataURLtoBlob(base64);
var myUrl = URL.createObjectURL(myBlob);
downloadFile(myUrl,name);
}
downloadFileByBase64(base64Url, `${downloadName}.${suffix || 'pdf'}`);
}
};
export default downloadBase64;注意:移动端a标签模拟点击下载除了图片都会出现问题,不要考虑用base64来下载。另外前端调用接口下载时可能出现下载文件损坏,主要可能是responseType未设置,或mockjs包导致的,该问题详细可见笔者的《前端下载文件时损坏》这篇博客