upload上传文件类型的限制的几种方式(element)

12,723 阅读2分钟

「这是我参与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;

  })

};

参考链接

  1. element.eleme.cn/#/zh-CN/com…
  1. juejin.cn/post/697726…