天天看点

js vue上传文件判断文件格式 GIF JPG PNG

根据文件识别头信息获取图片文件的类型:

JPG:

文件头标识:

FF D8

文件尾标识:

FF D9

PNG:

文件头标识 (8 bytes)

89 50 4E 47 0D 0A 1A 0A

GIF:

文件头标识 (6 bytes)

47 49 46 38 37 61

or

47 49 46 38 39 61

vue上传文件判断文件格式 GIF JPG PNG:

<template>
  <div>
    <div ref="drag" id='drag' @drop="bindEvents" @dragover="onDragover">
      <input type="file" name="file" @change="handleFileChange">
    </div>
    <button @click="uploadFile">上传文件</button>
  </div>
</template>
<script>
export default {
  data() {
    return {
      file: null
    }
  },
  methods: {
    onDragover(event) {
      event.preventDefault()
    },
    bindEvents(event) {
      event.preventDefault();
      const [ file ] = event.dataTransfer.files
      this.file = file
    },
    async uploadFile() {
      if (!await this.isImage(this.file)) { //判断是否是图片
        alert('文件格式不对!')
        return
      }
      const form = new FormData()
      form.append('name', 'file')
      form.append('file', this.file)
      const res = await this.$http.post('/uploadfile', form)
    },
    handleFileChange(e) {
      const [ file ] = e.target.files
      if (!file) return
      this.file = file
    },
    async isImage(file) {
      return await this.isGif(file) || await this.isPng(file) || await this.isJpg(file)
    },
    blobToString(blob) {
      return new Promise(reslove => {
        const reader = new FileReader()
        reader.onload = function() {
          const ret = reader.result.split('')
                      .map(v => v.charCodeAt())
                      .map(v => v.toString(16).toUpperCase())
                      .join(' ')                   
          reslove(ret)
        }
        reader.readAsBinaryString(blob) // 开启读取
      })
    },
    async isPng(file) { //判断是否是png
      const ret = await this.blobToString(file.slice(0, 8))
      return (ret === '89 50 4E 47 D A 1A A')
    },
    async isJpg(file) { //判断是否是jpg
      const len = file.size
      const start = await this.blobToString(file.slice(0, 2))
      const tail = await this.blobToString(file.slice(-2, len))
      return (start === 'FF D8') && (tail == 'FF D9')
    },
    async isGif(file) { //判断是否是gif
      // GIF89a 和 GIF87a
      // 前面6个16进制, '47 49 46 38 39 61' or '47 49 46 38 37 61'
      const ret = await this.blobToString(file.slice(0, 6))
      return (ret === '47 49 46 38 39 61') || (ret === '47 49 46 38 37 61')
    },
  }
}
</script>