文章目录
前言
File、 Blob、 dataURL 与 docURL
在日常项目开发中,会有这样的场景:
- 将用户上传的文件转换为
base64
编码格式dataURL或Blob
对象,上传至服务端 - 保证资源链接安全性
这里会需要,File、 Blob、 dataURL 与 docURL 相互之间转换生成
一、转换规则说明
文章下述内容中会有使用
文章术语 :
file(File 对象) blob(Blob 对象) dataURL(base64编码资源路径) docUrl(url:与创建它的窗口中 document 绑定)
- file -> dataURL | docUrl
- dataURL -> file | blob
- blob -> file | dataURL | docUrl
二、转换api
所有方法入参应做一层校验判断是否合法。
校验传入是否合法(简单校验)
这里对于base编码形式的dataURL
进行了简单的正则匹配校验,File
| Blob
对象进行原型判断
vertifyEntryValue(value: string | File | Blob) {
if (typeof value === 'string') {
return /^data:(.*);base64/.test(value);
} else {
return value instanceof File || value instanceof Blob;
}
}
公共方法
_transformBase64
: 处理base64编码
/**
* 处理base64编码
* @param dataURI base64编码
* @returns {obj}
* @returns {obj.mimeString} 资源格式信息 eg. image/png
* @returns {obj.u8arr} Uint8Array实例
*/
_transformBase64(dataURI: string) {
const arr = dataURI.split(',');
const byteString = atob(arr[1]);
const mimeString = arr[0].match(/:(.*?);/)![1];
const ab = new ArrayBuffer(byteString.length);
const u8arr = new Uint8Array(ab);
for (let i = 0; i < byteString.length; i++) {
u8arr[i] = byteString.charCodeAt(i);
}
return {
mimeString,
u8arr,
};
}
1. File转换体系
因
File
构造函数基于Blob
,所以此api也适用于blob
1.1 file | blob —> dataURL
FileReader转换是异步过程,使用Promise异步化
// file -> dataURL & blob -> dataURL
fileLikeToBase64(value: File | Blob) {
return new Promise(
(
resolve: (value: string) => void,
reject: (reason: {
code: 'custom' | 'system';
msg: string;
error?: any;
}) => void,
) => {
if (!this.vertifyEntryValue(value)) {
reject({
code: 'custom',
msg: this.vertifyErrMsg,
});
}
const fileReader = new FileReader();
fileReader.readAsDataURL(value);
fileReader.onload = (e: ProgressEvent<FileReader>) => {
const dataURL = e.target?.result;
if (typeof dataURL === 'string') {
resolve(dataURL);
} else {
reject({
code: 'custom',
msg: '转换结果不是base64编码dataURL',
});
}
};
fileReader.onerror = (err) => {
reject({
code: 'system',
msg: 'system error',
error: err,
});
};
},
);
}
1.2 file | blob —> docUrl
-
URL.createObjectURL() 静态方法会创建一个 DOMString,其中包含一个表示参数中给出的对象的URL。这个 URL 的生命周期和创建它的窗口中的 document 绑定。
-
URL.revokeObjectURL() 静态方法用来释放一个之前已经存在的、通过调用 URL.createObjectURL() 创建的 URL 对象。
blobToDocUrl(value: File | Blob) {
const docUrl = window.URL.createObjectURL(value);
window.addEventListener('close', () => {
window.URL.revokeObjectURL(docUrl);
});
return docUrl;
}
2. dataURL 转换体系
base64编码形式dataURL
使用_transformBase64
处理后,使用 File
| Blob
构造函数创建实例
2.1 dataURL -> file
base64ToFile(dataURI: string, filename = 'file') {
const { u8arr, mimeString } = this._transformBase64(dataURI);
return new File([u8arr], `${filename}.${mimeString.split('/')[1]}`, {
type: mimeString,
});
}
2.2 dataURL -> blob
base64ToBlob(dataURI: string) {
const { u8arr, mimeString } = this._transformBase64(dataURI);
return new Blob([u8arr], { type: mimeString });
}
3. blob 转换体系
3.1 blob -> dataURL | docUrl
见此文章 File转换体系 部分
3.2 blob -> file
利用File Api讲blob转成File对象
blobToFile(value: Blob, filename = 'file') {
return new window.File([value], filename, { type: value.type });
}