上传图片时,需要校验文件是否是图片且符合要求的类型(JPG、PNG等),单纯通过input返回的type无法确定上传文件的真实类型(修改文件后缀后,type将无法正确识别)
解决方法:通过FileRender
读取文件,获取文件的二进制内容,通过二进制文件的文件头判断文件的真实类型
/**
* 图片类型校验
* @param num 待处理数字
* @returns
*/
export const verifyImageType = (file: Uint8Array, type: Array<ImageType>): boolean => {
const imgType = {
JPG: [255, 216],
PNG: [137, 80],
BMP: [66, 77],
JPEG: [255, 77]
};
return type.some((item) => file.slice(0, 2).toString() === imgType[item].toString());
};
/**
* 图片校验
* @param file 需要校验的文件
* @param limit 该文件的校验条件
* @returns
*/
export const verifyImage = async (file: File, limit: ImgLimit): Promise<boolean> => {
const unit8Array = new Uint8Array(await fileToArrayBuffer(file));
// 校验图片类型
const isRightType = isDefined(limit.type) && verifyImageType(unit8Array, limit.type);
let isRightSize = true;
let isRightScale = true;
if (limit.size) {
// 图片大小限制
const unit = ['k', 'm', 'g'];
const num = +limit.size.slice(0, -1);
const index = unit.indexOf(limit.size.slice(-1).toLocaleLowerCase());
isRightSize = 1024 ** (index + 1) * num < unit8Array.length;
}
if (limit.scale && isRightType) {
// 图片比例限制
const { width, height } = await loadImageSize(file);
isRightScale = limit.scale?.[0] === width && limit.scale[1] === height;
}
return isRightType && isRightSize && isRightScale;
};
参考资料