首页 > 基础资料 博客日记
【JavaScript 】获取真实的文件类型
2024-09-09 14:00:06基础资料围观105次
在系统上传文件时,有用户会直接修改文件名后缀,使其与系统要求一致后再上传,而html+javascript常用的上传文件方法难以判断文件的真实类型(此处也易恶意上传脚本文件的情况)
为此我们可以通过读取文件的二进制数据的前几个字节(通常称为“魔法数字”或文件签名)来尝试识别文件的类型。这些字节通常包含特定的ASCII字符或十六进制值,可以用来区分不同类型的文件格式。
一、代码示例
使用FileReader API读取文件的前几个字节,根据这些字节来确定文件类型:
/**
* 提取文件类型
* 文件名后缀可以随意修改,只有在读取的时候才能获取真实的文件类型,以防有人恶意上传不符合的文件
* 如果返回数据为null则没有匹配到符合的文件名,可能是漏了,也可能是不存在的文件类型,使用时需核查
*
* 微软和WPS生成的的word excel ppt等文件码不一致,且没有区分具体文件后缀,所以在判断相应的码后再解析文件名后缀
* */
export const getFileType = function(row) {
return new Promise((reslove, reject) => {
const file = row.file ? row.file : row.raw ? row.raw : row
const name = row.name || file.name
// console.log(file)
const reader = new FileReader()
reader.onload = evt => {
let realMimeType = ''
const arr = new Uint8Array(reader.result).subarray(0, 4)
// 将截取的result和magic number比较
let header = ''
for (let i = 0; i < arr.length; i++) {
header += arr[i].toString(16)
}
// 在这里可以得到上传图片的真实mintype类型
// 在这里执行你的逻辑,该方法是异步执行
if (header.indexOf('89504e47') === 0) {
realMimeType = 'png'
} else if (header.indexOf('424d') === 0) {
realMimeType = 'bmp'
} else if (header.indexOf('ffd8ffe0') === 0 || header.indexOf('ffd8ffe1') === 0 || header.indexOf('ffd8ffe2') === 0 || header.indexOf('ffd8ffe3') === 0) {
realMimeType = 'jpeg' // JPG/JPEG
} else if (header.indexOf('25504446') === 0) {
realMimeType = 'pdf'
} else if (header.indexOf('504b34') === 0) {
realMimeType = name.substr(name.lastIndexOf('.')).substr(1).toLowerCase()
} else if (header.indexOf('d0cf11e0') === 0 || header.indexOf('3c3f786d') === 0) {
realMimeType = name.substr(name.lastIndexOf('.')).substr(1).toLowerCase()
} else if (header.indexOf('47494638') === 0) {
realMimeType = 'gif'
} else if (header.indexOf('52617221') === 0) {
realMimeType = 'rar'
} else if (header.indexOf('57617665') === 0 || header.indexOf('52696666') === 0) {
realMimeType = 'wav'
} else if (header.indexOf('41564920') === 0) {
realMimeType = 'avi'
} else if (header.indexOf('504b0304') === 0) {
realMimeType = 'zip'
} else if (header.indexOf('50415220') === 0) {
realMimeType = 'par2'
} else if (header.indexOf('7b5c727466') === 0) {
realMimeType = 'rtf'
} else {
realMimeType = null
}
console.log(header, realMimeType)
reslove(realMimeType)
// console.log(header, realMimeType)
}
reader.readAsArrayBuffer(file)
})
}
1、使用 new FileReader(),读取将传入的文件转成二进制数据,如果是base64或其他格式可依对应方法转换成二进制数据。
2、使用Uint8Array方法将文件流转化成文件流。
3、依据第0位开始的前几位编码来判断文件类型。
二、几种常见的文件类型编码:
89504e47:png
424d:bmp
ffd8ffe0:jpeg、jpg
ffd8ffe1:jpeg、jpg
ffd8ffe2:jpeg、jpg
ffd8ffe3:jpeg、jpg
25504446:pdf
47494638:gif
52617221:rar
57617665:wav
52696666:wav
41564920:avi
504b0304:zip
50415220:par2
7b5c727466:rtf
504b34:无法判断真实文件名,可依据文件名后缀判断
d0cf11e0:无法判断真实文件名,可依据文件名后缀判断
3c3f786d:无法判断真实文件名,可依据文件名后缀判断
备注:这种方法并不完美,只能检测一些常见的文件类型。某些文件类型可能具有相同的或类似的头部,而且有些文件可能不遵循标准的文件签名,因此这种方法可能无法准确识别所有类型的文件。此外,文件可能被修改或封装在其他格式中,这也会影响检测的准确性。
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:jacktools123@163.com进行投诉反馈,一经查实,立即删除!
标签: