「这是我参与2022首次更文挑战的第5天,活动详情查看:2022首次更文挑战」
在上传文件过程中,设计需求上这边总是需要对上传文件进行限制和判断,避免用户的盲操作,导致上传文件类型不对后,无法得到正确的信息,造成不好的体验影响,所以在页面上我们需要对文件类型做判断
这里我们采用的是element的upload上传组件做例子,大多数上传组件类似,这里就不一一举例了,
我们这次是对图片类型做限制
首先我们使用组件
<el-upload
accept="image/*"
class="avatar-uploader"
action="https://jsonplaceholder.typicode.com/posts/"
:before-upload="beforeAvatarUpload"
</el-upload>
accept 属性只能与 配合使用。它规定能够通过文件上传进行提交的文件类型。
值 | 描述 |
---|---|
audio/* | 接受所有的声音文件。 |
video/* | 接受所有的视频文件。 |
image/* | 接受所有的图像文件。 |
MIME_type | 一个有效的 MIME 类型,不带参数。请参阅 IANA MIME 类型,获得标准 MIME 类型的完整列表。 |
我们从element官网可以看到对文件上传前的钩子是before-upload
通过文件类型判断
在大多数文件中,在文件file属性中,有type属性,所以我们可以根据type属性进行判断
beforeUpload(file) {
const isJPG = file.type === 'image/jpeg'
if (!isJPG) {
this.$message.error('上传头像图片只能是 jpg 格式!');
}
return isJPG;
}
通过文件名称判断
但是仍然有少数文件是没有type类型的,我曾经就碰到过,不知道是系统的原因,还是文件自身的缘故,我们我们需要第二道判断方法,进行限制
这里就是文件名后缀了,无论是windows还是mac os,文件都有相应的后缀名
所以
beforeUpload(file) {
const typeArry = ['.jpg', '.png', '.bmp', '.JPG', '.PNG', '.BMP', '.gif', '.GIF'];
const type = file.name.substring(file.name.lastIndexOf('.'));
const isImage = typeArry.indexOf(type) > -1;
if (!isImage) {
this.$message.error('上传文件必须为图片');
}
return isImage;
},
通过读取文件的二进制数据来判断文件类型
以上,两种方式可以解决绝大多数的文件,但是总是存在个别顽固分子,既没有type,也没有文件名后缀,或者是其他因素,无法进而判断的,
所以我们可以通过读取文件的二进制数据来借以判断文件类型
在这篇文章中,也有详细的说明如何做Antd Upload单个图片的校验和上传?
主要是通过魔数来判断。 PNG的魔数是 0x89 50 4E 47 0D 0A 1A 0A,我们可以通过读取文件二进制的前8个字节来一一比对来判定文件的类型:
常见的图片魔数
JPEG (jpg),文件头:FFD8FF
PNG (png),文件头:89504E47
GIF (gif),文件头:47494638
TIFF (tif),文件头:49492A00
const getBuffers = (file) => {
return new Promise((resolve, reject) => {
const reader = new FileReader();
reader.readAsArrayBuffer(file.slice(0, 8));
reader.onload = () => {
resolve(reader.result);
};
reader.onerror = reject;
})
};
参考链接