• Using HTML attributes

    <input type="file" accept=".mp4, .mov">
    <input type="file" accept=".png, .jpg, .jpeg, .gif">
    Copy the code

    Disadvantages: The Accept attribute can be removed from the console, bypassing the limitation

  • File MIME type

    const fileType = Object.assign(Object.create(null), {
      'video': ['video/mp4'.'video/quicktime'].'image': ['image/png'.'image/jpeg'.'image/gif'],})const validFileType = (type, mimeType) = > fileType[type].includes(mimeType)
    const validator = async (type, files) => {
      const result = files.map(file= > validFileType(type, file.type)).every(boolean= > boolean)
      return { valid: result }
    }
    Copy the code

    Disadvantages: Can be tampered with file extensions, circumvent restrictions

  • Through file header data

    const blobToString = async blob => {
      const buffer = await blob.arrayBuffer()
      return [...new Uint8Array(buffer)].map(n= > n.toString(16).toUpperCase().padStart(2.'0')).join(' ')}const fileType = Object.assign(Object.create(null), {
      'isMp4': str= > ['00 00 00 18'.'00 00 00 20'.'00 00 00 1C'].includes(str),
      'isMov': str= > str === '00 00 00 14'.'isJpg': str= > str === 'FF D8 FF E0'.'isPng': str= > str === '89 50 4E 47'.'isGif': str= > str === '47 49 46 38'
    })
    const validFileType = Object.assign(Object.create(null), {
      'video': str= > fileType['isMp4'](str) || fileType['isMov'](str),
      'image': str= > fileType['isJpg'](str) || fileType['isPng'](str) || fileType['isPng'](str) || fileType['isGif'](str)
    })
    const validator = async (type, files) => {
      const result = (await Promise.all(files.map(file= > blobToString(file.slice(0.4)))))
        .map(str= > validFileType[type](str))
        .every(boolean= > boolean)
      return { valid: result }
    }
    Copy the code

    Turn the file header data into hexadecimal characters to prevent tampering with file extensions