以localStorage为例、无法存储文件引用对象;即使我们存了,或者使用JSON.stringify转化,在获取的时候,也只能获取到一个空对象;
因为localStorage只能存储字符串、所以我们可以先把图片、转化为base64去存储;
在需要使用的时候在转化base64为文件对象;
其实存储图片这个需求、也不应该是通过localStorage去存储、因为对应浏览器都有相应大小的限制、只有5M左右;可以使用indexDB或其他存储手段
这里我做的业务时页面代码、需要存储选中的图片文件、也就是将文件转化为base64!
const uploadFile = async (file) => {
const fileReader = new FileReader();
fileReader.onload = function () {
const result = this.result; //文件内容
// 在此处拿到的即为base64格式内容
}
fileReader.readAsDataURL(file);
};
如果是直接转对应的图片存储为以下代码
// 转base64方法
export const getBase64Image = (img) => {
const canvas = document.createElement('canvas');
canvas.width = img.width;
canvas.height = img.height;
const ctx = canvas.getContext('2d');
ctx.drawImage(img, 0, 0, img.width, img.height);
const ext = img.src.substring(img.src.lastIndexOf('.') + 1).toLowerCase();
const dataURL = canvas.toDataURL('image/' + ext);
return dataURL;
};
使用
const image = new Image();
image.crossOrigin = 'Anonymous';
image.src = '图片地址';
image.onload = function () {
var base64 = getBase64Image(image);
console.log(base64);
};
以上拿到base64数据、如果我们的接口支持base64上传、那就直接用此base64上传即可、我们的项目因为使用的是公共服务、所以没人愿意在单独写接口了、那也问题不大、我们在将base64转回来;
如果直接使用new File转化,在ios会有一些兼容问题、所以我们使用如下方法转化、先将base64转华为blob、在将blob数据转化为File文件
// 将base64转化为blob对象
export const dataURLtoBlob = (base64Data) => {
var arr = base64Data.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 });
};
// 将blob转化为File文件
export const blobToFile = (theBlob, fileName) => {
// 这里直接使用theBlob设置自身属性会有eslint no-param-reassign报错、不能直接改变参数对象数据、所以这里使用Reflect代理
Reflect.set(theBlob, 'lastModifiedDate', new Date());
Reflect.set(theBlob, 'name', fileName);
return theBlob;
};
使用
const blob = dataURLtoBlob(base64Data);
const file = blobToFile(blob, '对应文件名');
const formData = new FormData();
formData.append('file', file);
...
以上