前言:
🪵Blob和File可以归为一类,它们都是数据
📦formData是一个应用数据的场景
使用场景:
图片、音视频、Excel等这几种常见的资源类型,如何从实现前端上传到服务器?
📝原生的 File 对象new File(['<h1> Blob </h1>'],'FileName',{...opytion})
- 纯粹的文件,通常表示我们使用
<input type="file">选择的 FileList 对象(没有经过任何处理的文件) - File 对象也是二进制对象,从属于 Blob;也就是说 File 是 Blob 里的一个小类,Blob 的属性和方法都可以用于 File,而 File 自己也有自己特有的属性和方法。对于 Blob 和 File 都有的属性,推荐使用 Blob 的属性
📑转化后的 Blob 对象 new Blob(['<h1> Blob </h1>'],{...option})
- 表示二进制大对象,并不是前端的特有对象,而是计算机界的通用术语,一个包含有只读原始数据的类文件对象(不可修改的二进制文件)
- Blob只有一个slice方法,实现对文件的分割(注意这里并不违背Blob的只读性,slice只是复制指定范围内的Blob数据)
Blob.slice(start, end ,contentType)(文件的断点续传利用了改特性) - 例如,图片 canvas 合成后的 base64 转化为 Blob 对象,录音音频经过算法生成的数据转化 Bloab 对象等
🗒️FormData 对象new FormData()
- 使用 FormData 可以异步上传一个二进制文件,而这个二进制文件,就是上面讲的Blob对象
- 文件上传服务器时,FormData 就是封装的一个 form 表单,应用数据(Blob)的一个场景
- 给 FormData 对象添加一下文件的信息数据
new FormData().append('fileKey',file)【formData 实例添加 file 对象】,然后通过1请求上传服务器
其它:
✍️图片链接转 base64(异步)
/**
* url 转化 base64
* @param { Array } imageArr 图片链接
* @return { Promise }
*/
transformationBase(imageArr) {
let arr = [];
return new Promise((resolve) => {
imageArr.forEach((item) => {
let image = new Image();
image.src = item;
image.setAttribute('crossOrigin', 'Anonymous');
image.onload = () => {
let canvas = document.createElement('canvas');
canvas.width = image.width;
canvas.height = image.height;
let ctx = canvas.getContext('2d');
ctx.drawImage(image, 0, 0, image.width, image.height);
// 获取图片格式 png gif jpg...
let ext = image.src
.substring(image.src.lastIndexOf('.') + 1)
.toLowerCase();
// 转化方法 toDataURL('image/文件类型')
let dataURL = canvas.toDataURL('image/' + ext);
arr.push(dataURL);
// 通过数组长度判断是否全部完成
if (arr.length == imageArr.length) resolve(arr);
};
});
});
}
🎲文件转成 Base64
FileReader: 前面提到 Blob对象是一个只读对象(二进制对象),直接读取只能拿到一堆0101二进制数据,因此需要借助专门的工具来读取,这个工具就是 FileReader。通过 FileReader 可以将 Blob 读取为不同的格式数据。(考虑兼容性问题)
通过FileReader.readAsDataURL(blob) 就是将二进制数据读取并编码为 Base64 格式,FileReader.readAsText(blob) 就是将二进制数据读取并编码为字符串形式。
/**
* 文件 转成 Base64
* @param { Blob|file } file 文件
* @return { Promise }
*/
function readFile(file) {
retrun new Promise((resolve)=>{
let reader = new FileReader();
reader.readAsDataURL(file);
reader.onload = function (e) {
reader?.result && resolve(reader.result)
}
})
}
🧷window.open下载
/**
* window.open下载
* @param { String } url 文件下载链接
*/
function downloadEvt(url) {
window.open(url, '_self');
}
优点
- 简单方便直接
缺点
- 会出现URL长度限制问题
- 需要注意url编码问题
- 无法获取下载进度
- 无法在header中携带token做鉴权操作
- 无法直接下载浏览器可直接预览的文件类型(txt、png、pdf会直接预览)
- 无法判断接口是否返回成功
🖇️更多下载方