关于判断上传图片时前端判定是否为图片的问题
今天在写图片上传功能时,想要在前端检测用户选中的文件是否为图片的功能,首先当然是在 input 里面设置 accept="image/*" 啦,但是这样也不能保证上传的一定是图片,因为用户可以在选择文件框中修改展示的文件后缀,令其可以选中所有类型的文件。于是,便需要在 js 中进行判断。
我先去谷歌了一下其他人的方法,通常大家有两种判断方法,其一是获取上传文件的 type 属性值,但是这并不能防范用户修改文件后缀名为图片后缀后上传文件,另一种方法是判定文件的 MIME TYPE,该方法调用了 readAsArrayBuffer 方法,经过几步操作后获取到了文件类型签名,于是便可比对该签名与对应允许上传的图片类型签名是否吻合,如吻合,便可上传,详情点击使用 JavaScript 检测文件 MIME TYPE。
我觉得第一种防了和没防也没啥区别,第二种有点繁琐,便先去测试一下我先前写的头像上传功能,看其能不能加载错误的文件。一试,哇哦,加载大失败,还没报错,有意思。查看了一下代码,加入了几个 console 进行了测试,发现关键在于 Image 对象。
当使用 Image 对象时,我们通常会先对其 src 属性进行赋值,之后监听 onload 事件,并在其中编写或传递函数来回调。当我们传入非图片文件时,图片不会调用 onload 事件,于是非图片文件便不会上传啦。
这是代码:
HTML
<input type="file" accept="image/*" multiple="multiple" @change="uploadChange" />
JavaScript(该方法在 Vue 的 methods 方法中)
uploadChange(event) { const target = event.target; const files = target.files; for (let file of files) { let reader = new FileReader(); reader.onload = e => { let img = new Image(); img.src = e.target.result; img.onload = () => { // do something }; }; // 用于将Blob对象转换成base64编码 reader.readAsDataURL(file); } }