JS图片上传校验函数分辨率校验始终返回true问题求助
问题根因
你的分辨率校验逻辑始终返回true,核心是三个逻辑错误:
- 混淆了同步赋值和异步执行逻辑:
img.onload = 回调函数这个操作是同步执行的,赋值完成后表达式的返回值就是这个回调函数本身,而函数属于JavaScript中的真值,因此外层if判断永远成立,直接把result设为true,根本不会等待图片实际加载完成读取宽高。 onload回调里的return只作用于回调函数本身,不会把校验结果返回给外层的checkUploadImage函数,就算宽高判断逻辑执行了,结果也无法传到外层。- 图片加载是异步操作,原函数采用同步返回值的设计本身就存在缺陷:就算修正了if判断的写法,函数执行到return语句时onload回调还未触发,永远拿不到真实的分辨率校验结果,必须改成异步返回。
修正后的代码
将函数改为返回Promise的异步实现,等图片加载完成、拿到实际宽高后再返回校验结果,同时补充图片加载失败的异常处理,避免内存泄漏:
const checkUploadImage = (objToCheck) => { const { obj, type, size, height, width } = objToCheck; // 先走同步可完成的大小、格式校验 if (obj.size > size * 1024) { return Promise.resolve({ pass: false, reason: '图片大小超出限制' }) } if (!type.includes(obj.type)) { return Promise.resolve({ pass: false, reason: '图片格式不符合要求' }) } // 分辨率校验走异步逻辑 return new Promise((resolve) => { const img = new Image(); const objectUrl = window.URL.createObjectURL(obj); img.src = objectUrl; img.onload = () => { const actualHeight = img.height; const actualWidth = img.width; // 释放创建的对象URL,避免内存泄漏 window.URL.revokeObjectURL(objectUrl); const pass = actualHeight >= height && actualWidth >= width; resolve({ pass, reason: pass ? '' : '图片分辨率不符合要求' }) } img.onerror = () => { window.URL.revokeObjectURL(objectUrl); resolve({ pass: false, reason: '图片解析失败,请重新选择文件' }) } }) }; export default checkUploadImage;
调用方式
由于分辨率校验是异步逻辑,调用时不能直接同步获取返回值,需要通过await或者.then拿到校验结果,以下是在input change事件中的使用示例:
const inputChangeHandler = async (event) => { const file = event.currentTarget.files[0]; if (!file) return; const checkResult = await checkUploadImage({ obj: file, type: ['image/jpeg', 'image/jpg'], size: 5 * 1024, height: 70, width: 70, }); if (!checkResult.pass) { // 校验失败,提示对应错误 alert(checkResult.reason); return; } // 校验通过,执行后续上传等逻辑 console.log('图片校验通过,开始上传'); }
内容的提问来源于stack exchange,提问作者Volodymyr Tabashnyuk
相关产品推荐
相关产品推荐

