> 通过base64 获取文件头判断文件类型并不准确,如果想要获取文件真实类型,需要获取文件二进制头,每种格式都有特有的二进制头。所以需要前端读取文件流,比较文件头,判断文件真实格式。
```
function stringToBytes(string) {
return [...string].map((character) => character.charCodeAt(0))
}
function readBuffer(file, start = 0, end = 2) {
return new Promise((resolve, reject) => {
const reader = new FileReader()
reader.onload = () => {
resolve(reader.result)
}
reader.onerror = reject
reader.readAsArrayBuffer(file.slice(start, end))
})
}
function check(headers) {
return (buffers, options = { offset: 0 }) =>
headers.every((header, index) => header === buffers[options.offset + index])
}
const isPDF = check(stringToBytes('%PDF'))
const isPNG = check([0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a])
export const checkFileType = async (file, accept = '*') => {
const buffers = await readBuffer(file, 0, 8)
const uint8Array = new Uint8Array(buffers)
const acceptList = accept.split(',')
for (let i = 0, length = acceptList.length; i < length; i++) {
if (acceptList[i] === 'pdf' && isPDF(uint8Array)) return true
else if (acceptList[i] === 'png' && isPNG(uint8Array)) return true
}
return Promise.reject()
}
```
前端文件类型校验