sleepyShen1989 / blog

MIT License
0 stars 0 forks source link

【实战】前端判断文件类型demo #22

Open sleepyShen1989 opened 1 year ago

sleepyShen1989 commented 1 year ago

demo1

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <input type="file" id="upload" />
    <script>
        const uploadInput = document.getElementById('upload')

        //将十进制的number类型数据转成十六进制表示的字符串
        function numToHex(number) {
            let result = number.toString(16);
            return result.padStart(2, "0").toUpperCase();
        }

        function isJpeg(buffer){
            var uint8Array = new Uint8Array(buffer);
            var len = uint8Array.length;
            if (
                numToHex(uint8Array[0]) === "FF" &&
                numToHex(uint8Array[1]) === "D8" &&
                numToHex(uint8Array[len - 2]) === "FF" &&
                numToHex(uint8Array[len - 1]) === "D9"
            ) {
                return "jpeg";
            }
            return null;
        }

        uploadInput.addEventListener('change', (e)=>{
            // console.log(e.target.files[0])
            const reader = new FileReader();
            reader.readAsArrayBuffer(e.target.files[0], 'utf-8'); //发起异步请求
            reader.onload = function () {
                //读取完成后,数据保存在对象的result属性中
                const type = isJpeg(reader.result);
                console.log(type);
            }
        })
    </script>
</body>
</html>

demo2

/**
* 获取网络文件并转化为ArrayBuffer
*/
function loadFile(fileUrl) {
 return new Promise((resolve, reject) => {
   const xhr = new XMLHttpRequest();
   xhr.onload = function () {
     if (xhr.status === 200) {
       resolve(xhr.response);
     }
   };
   xhr.onerror = reject;
   xhr.open('GET', fileUrl, true);
   xhr.responseType = 'arraybuffer';
   xhr.send('');
 })
}

/**
* 获取本地文件并转化为ArrayBuffer
*/

//input[type="file"].onchange 回调事件
function onFileChange(file) {
  return new Promise(async (reslove, reject) => {
    if (!file) {
      return reslove(false);
    }
   const FR = new FileReader();
   const fileChunk = file.slice(offset, size + offset);
   FR.readAsArrayBuffer(fileChunk);
   FR.onload = (e) => {
       //e.target.result便是所需ArrayBuffer
       const ArrayBuffer = e.target.result;
      //do something
    }
  });
}

//文件签名列表,作为文件上传类型的白名单
const fileSignatures = {
  pdf: [
    {
      extension: 'pdf',
      signature: '25504446',
      size: 4,
      offset: 0,
    },
  ],
  //....
};

function getfileSignature(file, size, offset) {
  return new Promise((resolve, reject) => {
    try {
      const FR = new FileReader();
      const fileChunk = file.slice(offset, size + offset);
      FR.readAsArrayBuffer(fileChunk);
      FR.onload = (e) => {
        const view = new DataView(e.target.result as ArrayBufferLike);
        let fileSignature = '';
        for (let i = 0; i < view.byteLength; i += 1) {
          let byte = Number(view.getUint8(i)).toString(16).toUpperCase();
          byte.length === 1 && (byte = '0' + byte);
          fileSignature += byte;
        }

        resolve(fileSignature);
      };
    } catch (e) {
      reject(e);
    }
  });
}

function judgeFileType(file) {
  return new Promise(async (reslove, reject) => {
    if (!file) {
      return reslove(false);
    }
    try {
      const fileInfoArr = file.name.split('.');
      const fileType = fileInfoArr[fileInfoArr.length - 1];

      if (fileSignatures[fileType]) {
        for (let i = 0; i < fileSignatures[fileType].length; i++) {
          const fileSignature = await getfileSignature(file, fileSignatures[fileType][i].size, fileSignatures[fileType][i].offset);
          if (fileSignature === fileSignatures[fileType][i].signature) {
            return reslove(true);
          } else if (i === fileSignatures[fileType].length - 1) {
            return reslove(false);
          }
        }
      } else {
        return reslove(false);
      }
    } catch (e) {
      reject(e);
    }
  });
}

参考资料