文件上传之进度条与图片类型检测

今天要与大家分享的是文件上传功能。

其实上传文件没什么难得,只需要一个form表单,里面装一个input type=file即可,上传了文件,提交form就搞定,但这样的效果估计也仅仅在自己学习或测试的时候敢用,敢问现在哪个网站还敢把这么“清新脱俗”的上传效果放上去,那不得被吐槽致死。

进入重点,先说说文件上传进度条,最开始设计这个插件的时候,在网上找过,说用jquery提供的xhr能实现,当时也试了,可惜不行...无奈,只能手写一个原生ajax来实现,首先获取一个xhr对象,请不要告诉我这个xhr你不知道是什么东西...拿到这个对象后,将最终上传的文件对象获取到,注意我这里是一个input对应一个file,当需要上传多个文件时,是多个input来实现,获取到文件信息,如文件名称、大小(字节,如果大于1M,可以手写个方法转换为MB),如图:

new一个FormData(IE10+)然后将文件对象装进去,并且创建新变量:prev(上一次时间戳)、load(以上传大小,初始化0)、size(文件总大小)、prevProgress(当前进度,初始化0)

下面是比较关键的给xhr添加监听事件:

error(文件上传过程中失败的处理函数),就是一个提示框,也可以写一个覆盖这个方法;progress:也就是文件上传的进度了,e.loaded是当前已经上传的文件大小,loaded - load就是new Date().getTime()或者Date.now() - prev这个时间段内所上传的大小,大小除以时间段也就是speed,progress = Math.min(Math.round(loaded / size * 100), 100),这里加了Math.min是因为测试的时候发现如果上传一个接近0字节的文件,progress居然大于100...这样上传速度和上传进度都能获取到了,更新到dom,下面就是onreadystatechange:

上传成功后,获取到服务器返回的文件路径,执行afterUpload回调方法,一般都是想办法把返回的文件路径存放起来,等到最后和表单中其它信息一块提交保存到数据库。多文件上传是一样的原理。

首先说说里面几个比较棘手的问题:

1、当用户选中了一个文件A,当他想换一个文件时,都弹出上传文件框了,好,他点取消,那么文件A就没有了,个人认为这是浏览器一个坑爹的设计。当然也有解决办法,就是将上一次上传的文件缓存起来,等到确定上传的时候将缓存文件提交上去。更好的方法就是每个上传框对应两个form,两个form分别对应input type="file"(A、B’),每次点击“上传文件”按钮时,需要遍历A、B,找到第一个files为空的inpu(如A)t触发click,选择文件后,需要执行重置B对应的表单的操作;再次点击按钮,触发B的click操作,这里分两种情况,一种是选择了文件,那么重置A对应的表单,另一种情况是点击“取消”


虽然B的files为空,但是A的文件依然存在。点击“上传”按钮时,遍历A、B,找到files不为空的dom,获取到file放到FormData。

2、不知道大家发现没有,在Win10系统中上传文件,点击“上传文件”按钮,一般会在5秒后弹出上传文件的框,但是其它系统没有这个问题,经过多次测试发现,accept属性中指定的值越少越好,比如需要上传图片,一般的写法都是accept="image/*",在win10中最好写image/jpg、image/png、image/jpeg,bmp也可以,这样你会发现这个弹出层是光速反应,点击“上传文件”后,它立马就蹦出来了。微软的强推的东西果然有毒。

3、只是上传文件如图片还远远不够,有时候我们开发了图片上传功能,各方面细节也做的比较足,好,功能提测,然后...公司里面万恶的测试,居然搞一些文本文件,把后缀改成jpg,它表面上就变成了一个图片,然后我们点击这个假图片查看的时候就呵呵了...当然这也不能怪测试,毕竟她们是吃这碗饭的,也难为她们了,既然测出问题来了,就得有相应的解决方案。前端肯定是校验不了图片的真实类型的,需要在每次onChange时将文件传递到后端进行检测,因为我后端使用的java,这里就介绍java的校验方法吧:



了解java语言的小伙伴应该发现,后端使用的是SpringMVC,使用的是MutilpartFile接收文件,读取文件前4个字节(8位),然后检测文件头是否是上图定义的图片类型之一,这里特别需要注意的一点时,如果上传的图片需要缩放和裁剪,这样检测还是不够的,因为有的图片是PS搞出来,它还不是真实的图片,这种文件在裁剪和缩放时会报错造成失败,有点扯远了,毕竟这里还没有介绍裁剪插件...嗯,介绍的应该够用了大笑

赶紧上传插件参数图片:





今天本来想把文件切片上传也一起写上的,时间关系,下次再搞。

总结:最初我在一家公司面试的时候,介绍了这个插件,当时面试官问我这实现了真正的上传进度了吗,我当时想都没想,这肯定是啊,这进度都已经摆在上面了。但面试结束后,我发现需要等进度条到达100%后才将请求提交到后端,所以这是一个假的进度条尴尬...它只是让用户看到了一个假的进度条,作为开发者的我就受不了了,怎么能自己欺骗自己,对于一个搞技术的人,我要求自己实事求是,所以下次会介绍文件切片,它会使进度条更接近实际情况,敬请期待...

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值