目录
问题
在前端开发过程中,文件上传功能几乎必不可少的,很多时候,我们在进行文件上传时,尤其是向普通用户开放文件上传功能时,一般都需要对上传文件的格式进行一些限制,以防止不良用户、黑客等将带有病毒脚本文件上传到服务器中,常见文件格式限制如下。
解决方案:
1、通过input标签的accept属性进行限制
我们可以通过HTML5中的 input file 标签的accept属性,根据自己的需求,在选择上传文件的时候,指定可见的文件类型格式(默认任意类型 )来进行限制。
<input type="file" id="oFile" name="myFiles" accept=".doc, .docx, .xls, .txt" onchange="upFile(event)" />
2、通过JS获取上传文件的file.type 或 file.name属性进行限制
在JS中,可以在上传事件中,通过file对象获取到上传文件的相关属性。
代码:
function upFile(event) {
const [ file ] = event.target.files || event.dataTransfer.files || this.file.files;
console.dir(file); // 文件对象
console.log(file.name); // 文件名称
console.log(file.type); // 文件类型
console.log(file.size); // 文件大小
// 对文件类型做简单限制:如:只允许上传 jpg png gif 这3种格式
if(!file.type && /\.(?:jpg|png|gif)$/.test(file.name)){
alert('对不起:上传的图片格式只能是:jpg, png, gif 格式!');
return false;
}
}
以上两种方式是我们最常见的文件上传类型限制方法,但是,如果单纯的以文件后缀名(扩展名)、文件类型进行截取的方式来进行限制,是非常容易遭到破解的,比如,用户要将文件的后缀名(扩展名),重命为你指定的可上传的文件类型,就绕过了你的限制,便可以完成上传。此时:我们根据文件的头信息,来判断文件真正的格式。
3、通过JS的FileReader方法获取上传文件的头信息进行限制
在JS中通过读取文件的十六进制的头信息,来进行限制,因为相同类型文件的文件头信息是相同的,即使用户修改了文件的后缀名(扩展名),但文件的头信息是不会改变的。
代码:
// 读取文件的二进制数据并将其转换为十六进制
function fileReader (blob) {
return new Promise((resolve, reject) => {
const reader = new FileReader();
reader.readAsBinaryString(blob);
reader.onload = (ret) => {
const res = reader.result.split('').map((o) => o.charCodeAt().toString(16).padStart(2, '0'));
resolve(res.join(' ').toUpperCase());
},
reader.onerror = (err) => {
reject(err);
};
});
};
// png格式
async function isPng(file) {
return (await fileReader(file.slice(0, 8))) == "89 50 4E 47 0D 0A 1A 0A";
};
// jpg格式
async function isJpg(file) {
const start = await fileReader(file.slice(0, 2));
const end = await fileReader(file.slice(-2, file.size));
return "FF D8" == start && "FF D9" == end;
};
// gif格式
async function isGif(file) {
const ret = await fileReader(file.slice(0, 6));
return "47 49 46 38 39 61" == ret || "47 49 46 38 37 61" == ret;
};
async function upFile(event) {
const [ file ] = event.target.files || event.dataTransfer.files || this.file.files;
console.dir(file); // 文件对象
console.log(file.name); // 文件名称
console.log(file.type); // 文件类型
console.log(file.size); // 文件大小
// 根据文件头信息进行判断限制:如:只允许上传 png 这种格式
if(!await isPng(file)){
alert('对不起:上传的图片格式只能是:png格式!');
return false;
}
}
4、通过第三方的file-type工具包来进行限制
file-type工具包也是用Js来进行封装的,其原理和上面的第3种方式一样,它支持的文件类型有几十种,几乎能满足我们的日常开发需求。
npm i file-type
Npm地址:file-type - npm
欢迎在评论区交流。
如果文章对你有所帮助,❤️关注+点赞❤️鼓励一下!博主会持续更新。。。。
我的博客原文:JavaScript对文件上传类型限制(根据文件头信息判断)
往期回顾
vue3.x使用prerender-spa-plugin预渲染达到SEO优化
vue3.x使用prerender-spa-plugin预渲染达到SEO优化