背景:产品需求,input框输入图片链接,点击检测按钮的时候需要判断该图片不超过2M
一、UI实现
<div className={less.detection}>
<input className={less.input} placeholder="请输入图片URL" onChange={(e) => this.inputOnChange(e)} />
<button type="button" className={less.button} onClick={(e) => this.identifyImage(e, inputUrl, 0)}>检测</button>
</div>
二、inputOnChange作用:获取value
inputOnChange(e) {
this.setState({
inputUrl: e.target.value,
});
};
三、identifyImage中校验图片链接格式和大小,我这边是分步校验的;
- 第一步:检验url是否正确,用正则;
- 第二步:检验是否有jpg/jpeg/png后缀;(这个其实真正的目的是想校验是否上传的是图片链接,这样写可能不好)
- 第三步:判断图片大小;
const urlRegexp = /^((https|http|ftp|rtsp|mms)?:\/\/)[^\s]+/;
identifyImage(e, image, index) {
if (e && e.preventDefault) {
e.preventDefault();
}
if (urlRegexp.test(image)) {
if (!((image.indexOf('.jpg') !== -1) || (image.indexOf('.jpeg') !== -1) || (image.indexOf('.png') !== -1))) {
Message.error('请输入正确的图片url');
return;
}
// 判断图片大小【Note:图片和项目必须是同源的,否则会报跨域错误】
this.judgeImageSizeByUrl('../../../static/1.png').then(result => {
// result.size是字节,2M=2097152字节
if (result.size > 2097152) {
this.handleImageErrorMsg('图片文件过大,请选择2MB以下的图');
} else {
// ......
}
});
}
};
四、judgeImageSizeByUrl判断文件大小
先前我以为最简单的办法,直接将url转换成blob对象,获取blob.size来比较;
其实不然,这种是错误的
judgeImageSizeByUrl(url) {
let blob = new Blob([url]);
if (blob.size > 2048) {
this.setState({
imageErrorMsg: '图片文件过大,请选择2MB以下的图',
});
return false;
}
}
正确的方法如下 (Note: 图片必须是同源的(即项目和图片必须是同源的))
judgeImageSizeByUrl = (url) => {
return new Promise((resolve, reject) => {
let xhr = new XMLHttpRequest();
xhr.open('GET', url);
xhr.responseType = 'blob';
xhr.onerror = () => {
reject();
};
xhr.onload = () => {
if (xhr.status === 200) {
resolve(xhr.response);
} else {
reject();
}
};
xhr.send();
});
}