
我刚入行那几年,文件上传这块,大家都是清一色的jQuery + ajaxfileupload,觉得这玩意儿就是yyds。为因为它能模拟异步上传,页面不用刷新,就能把文件...
我刚入行那几年,文件上传这块,大家都是清一色的jQuery + ajaxfileupload,觉得这玩意儿就是yyds。为因为它能模拟异步上传,页面不用刷新,就能把文件丢给后端,那时候觉得可牛逼了。
但这玩意儿就是个面子货,里面藏着个老掉牙的iframe。说白了,就是给你偷偷摸摸搞了个隐藏的表单,上传完了再想办法拿到iframe里面的结果。小文件还凑合,但凡文件稍微大点,或者网络环境差一点,这玩意儿就开始抽风,卡住、超时、安全报错,那叫一个酸爽。
我一次用它,是我刚跳槽到一家做在线教育的公司。老板让我负责一个PPT上传模块,说要支持超大文件,方便老师们备课。我拍着胸脯说没问题,直接搬出了我那套“祖传”的ajaxfileupload代码,心想这玩意儿跑了三年了,稳如老狗。
结果?demo当天,砸锅了。一个五十兆的PPT文件,传了五分钟,进度条卡在99%,然后直接报错,整个界面死在那里。客户就在旁边看着,老板脸色铁青,我当时恨不得找个地缝钻进去。事后,老板没骂我,但让我滚回去把这套上传逻辑彻底给我换掉,不然饭碗不保。
我那一个礼拜,头发都快薅没了,就是从那时候起,我彻底跟那玩意儿说再见,自己摸索出了一套新的打法。

现在看来,这才是最基础、最应该用的方案,但我当时就是被老代码锁死了脑子。那次被骂了之后,我做的第一件事就是扒开浏览器原生API的底裤。
我发现根本不用什么插件,浏览器早就内置了最好的工具:FormData。它就是一个虚拟的表单对象,能把我们想提交的数据,包括文件,全部包装起来。我直接抄起JS,创建一个FormData实例,把那个出错的File对象扔进去,然后用现代的fetch API带着它直接发给后端。
这玩意儿好在哪?它就是原汁原味的HTTP请求,没有iframe的干扰,能直接拿到上传进度,错误也好定位,上传成功率一下子就上去了。

*('file', theFile)。fetch方法,把头信息设置成空(让浏览器自己去定),然后把FormData丢进去。搞定!以前要写几十行代码和各种兼容判断,现在几行核心代码就解决了,速度快到飞起。
人不能总干重复劳动,对?有了方案一做底,我就琢磨着怎么把上传搞得更漂亮、更省事。于是我开始研究那些成熟的UI组件库。
现在随便哪个主流的前端框架,像什么Vue的Element UI,React的Ant Design,里面都有现成的上传组件。这玩意儿简直是懒人福音。我只需要在页面上拖一个上传区域,配置一下上传的接口地址,剩下的什么文件选择、拖拽上传、进度条显示、预览图生成、错误提示,组件全包了。
用这个方案,我基本上不用操心文件上传的细节,只需关注上传成功和失败后怎么处理业务数据就行。它底层也是用方案一的FormData那一套,但把UI和交互全封装好了,省了我起码两天写界面的时间。特别是对那些要求UI标准化的项目,简直是绝配。
后来我们接了个更大的项目,客户要求并发量必须顶得住,而且老师们上传的文件动不动就是几百兆的视频。要是所有文件都先传到我自己的服务器,再让我服务器转存到阿里云或者腾讯云,那带宽和服务器压力直接爆表。
这时候,我祭出了第三个方案:客户端文件直传云存储。
这套逻辑有点绕,但我搞定之后觉得这才是未来:
文件传到云端后,云端再通知我的后端“文件传好了”。这么一搞,我的服务器彻底解放了,带宽压力瞬间归零。别说几十兆,传几个G的文件,我的服务器也只是处理一个轻量级的签名请求,简直爽歪歪。
从那次事故之后,我再也没碰过那个老旧的ajaxfileupload。技术更新换代太快了,我们程序员不能抱着老黄历不放。我现在分享出来的这三套方案,无论你是想省事、想原生、还是想搞定高并发大文件,都能找到最适合自己的路子。别再活在iframe的阴影里了!