到目前为止,一共接触到了两种文件异步上传的jquery插件,虽然在名称上前者加了jquery进行区别,但两者都是基于jquery的扩展插件。

名称相似,架构也相似,但两者在应用上有很大的不同。

之前首次接触到的就是ajaxfileupload.js。当时没有接触太多的框架内容,了解到的第一个框架就是yii。但yii架构太大了,以至于配置文件都搞得我晕头转向。所以就照着慕课网上老师的从零搭建后台的课程,用原生的语言一步一步的搭建框架。然后前端样式方面用了bootstrap,也用的很烂,因为很多控件,都是固定样式,但后台有更多细节上的要求。比如说文件上传,bootstrap的上传文件那些加载项根本不知道什么时候去展示,怎么实现异步加载图片(后台上传图片大多是存在一个表单里,直接上传,但那样就会跳转到下一页,展示表单提交结果,但这样显然不是我想要的效果),也很迷茫。在网上找到的就是这个版本。好不容易做成一个demo,每次运行都会报错。如:jQuery.handleError is not a function ,或者 cannot call constructor of none,或者干脆就一直在error回调里转悠。

ajaxfileupload.js一直在很多博客里保存,然后好像没有谁站出来,说这是他写的,没有人维护,只能靠着一些大神自我改良,再Po出来,分享解决方案给大家。ajaxfileupload.js是基于比较旧的jquery写的,所以有些jquery方法不兼容,或者没了,如:jQuery.handleError is not a function ,解决方案:在ajaxfileupload.js文件里把handleError方法添加上。其他的 cannot call constructor of none或者一直在error回调里转,之前一直没有解决方案,也没有想过去调试源码。所以一直参考别人的意见。有的说在调用的时候,把dataType值改为JSON(之前一直都是小写,不知道大写有什么用),这样改之后确实越过了error回调报错,但json格式需要自己再用JSON.Parse方法解析一遍,所以我明显感觉这样是不对的。但当时没有其他的解决方案,也没有大神帮忙看看代码,只能将就着用。也有的说改ajaxfileupload.js中处理数据方法uploadHttpData中类型为json的处理函数(从这里可以看出前面的修改dataType值的方法明显是在逃避出错,所以错处的位置应该就在处理返回值函数里),从eval("data = " + data)改为eval("data = \" "+data+" \" "),这样改没什么效果,甚至从一个错误跳到另一个错误。这次通过chrome浏览器针对这个地方加断点进行调试,发现后面调用s.success之所以一直报错,是data处理过后,值为空。所以我做了一些调整,把data值调出来,后面就没有错误了。真开心,自己解决的!

17年到公司后,就接手了公司的一套基于ci的代码。框架里面,前端裹挟了大量的jquery插件,然后很多确实很好用,如easydialog,fancybox,97date,selecte2,kindeditor等等。像图片或文件上传就两种,一个是多图异步上传(基于Kissy,有预览那种),另一个就是jquery.ajaxfileupload.js(也有预览)。很尴尬,我之前的上传都没有考虑要把上传后的图片做一个预览,多图上传就更没辙了。在jquery.ajaxfileupload.js源码里,有作者的一些信息,包括作者的个人站点之类的。在作者的个人站上找到了GitHub地址,上面有一些作者写的小项目,里面就有jquery.ajaxfileupload.js。但我看了一遍源码,发现人家写的真好,整体的代码量要比ajaxfileupload.js少很多(虽然两者体量都不大的样子)。

对比一下,发现,ajaxfileupload.js适合那种主动触发提交的方式,可以携带多个参数,完全可以把其他表单字段加进去,一块提交,提交过程可控。而jquery.ajaxfileupload.js应该说更符合文件异步上传的概念,因为大多数后台场景都是上传一些图片资源,这时候选择文件就直接上传了,返回上传文件的地址,一步到位,可以将处理图片或文件的逻辑写到一个里面。但因为太聚合了,即使可以添加参数,即使触发提交方式可以修改成提交按钮,表单里一些数据依然很难添加的params中,元素初始化即绑定,没有机会像ajaxfileupload.js那样可控的上传。jquery.ajaxfileupload.js内部其实就是把file元素绑定了change事件,默认情况下(不绑定submit_button)修改即触发提交。

ajaxfileupload.js 初始化demo:

$("#loading").show();
$.ajaxFileUpload({
                url: url,                           //用于文件上传的服务器端请求地址
                type: 'POST',
                data: {
                    xx: xx,
                    xxx: xxx
                },
                secureuri: false,                   //是否需要安全协议,一般设置为false
                fileElementId: ['upload'],        //文件上传域的ID 在这里设置要上传的多个input的ID,单个直接字符串也行
                dataType: 'json',                   //返回值类型 一般设置为json
                success: function (data, status)    //服务器成功响应处理函数
                {
                    if (data.success == 1) {
                        $('#uploadPath').val(data.path);
                    } else {
                        eAlert(data.message);  // 基于easydialog封装的提示框,可替换成alert
                    }
                    $("#loading").hide();
                },
                error: function (data, status, e)//服务器响应失败处理函数
                {
                    alert(e);
                }
            });

jquery.ajaxfileupload.js 初始化demo:

$("#upload").ajaxfileupload({
            'action': url,
            'params': {
                'extra': 'info'
            },
            'onComplete': function(data) {
                if (data.success == 1) {
                    $('#uploadPath').val(data.path);
                } else {

                }
                $("#loading").hide();
            },
            'onStart': function() {
                $("#loading").show();
            },
            'onCancel': function() {
            }
        });

文末附两个文件:
jquery.ajaxfileupload.js
ajaxfileupload.js