问题点: 上传图片时,校验图片格式,通常校验图片后缀,如果是把 其他类型的文件,手动改成图片类型后缀,通过拿文件后缀的方式进行校验,将不会生效
解决方法,前端通过解析文件格式的方式,拿到文件的 魔术(每个图片文件都有自己单独的魔术),例如 png
格式,对应的文件魔术为 '89 50 4E 47',通过校验文件魔术的方式,避免用户手动改后缀上传的情况出现,且
上传的如果是一个脚本,也会有安全问题
代码
async function isImage (file) {
let gif = await isGif(file)
let png = await isPng(file)
let jpg = await isJpg(file)
return gif || png || jpg
}
async function isJpg (file) {
const res = await blobToString(file.slice(0, 3))
return res === 'FF D8 FF'
}
async function isPng (file) {
const res = await blobToString(file.slice(0, 4))
return res === '89 50 4E 47'
}
async function isGif (file) {
const res = await blobToString(file.slice(0, 4))
return res === '47 49 46 38'
}
async function blobToString (blob) {
return new Promise(resolve => {
const reader = new FileReader()
reader.onload = function () {
const res = reader.result
.split('')
.map(v => v.charCodeAt())
.map(v => v.toString(16).toUpperCase())
.map(v => v.padStart(2, '0'))
.join(' ')
resolve(res)
}
reader.readAsBinaryString(blob)
})
}
export default isImage