总结:ajax多文件上传,带进度条,前端篇

前言:
之前写过一个文件上传的模块,但是是多个input上传的,而且使用的是jQuery.form打包上传的,这样子就觉得还是有点不太方便。
1.提交的时候需要将整个form提交上去,换句话说就是需要将要提交的内容使用form将内容包括起来
2. 文件input虽然可以在页面上设置增减功能的办法调整文件数量,但是一般会设置上限(例如最多添加10个input,不然太多了页面就太乱了,当然这个情况在大部分情况下不是什么大问题,只有在要上传大量零散文件的时候才算有问题)

——————————————————————下面是我改进的方法———————————————————————

html:

<div class="input-group">
    <input type="file" id="attachment" multiple>
    <span id="progress_bar" style="color: #1AB394;display: table-cell"></span>
</div>
<ul id="attachment_list"></ul>
<button class="btn btn-file">upload file</button>

html中,只有input是主要的,其他的元素都可以按照需要替换掉。

js:

$.ajaxSetup({   //laravel中的request要带这个header参数
        headers: {
            'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
        }
    });

$('.btn-file').click(function(){
        if($('#attachment').val() == '')
            alert('请选择文件再上传');
        else{
            var path = $('#attachment')[0].files;
            var formData = new FormData();
            var names = '';
            /*
            提示:FormData不能写数组,array json都不行,能写简单的key->value键值对。
            键值对中key不能是中文,不然后台读不出来,而且要保证key的唯一性,
            那么我就用文件名path[i].name用md5加密一下好了,当然你也可以用自己喜欢的加密方式。
            因为laravel不能便利地读取所有file,只能用file('key')读取key值的value,
            是的,所以你不知道key值是读不出你要的东西的。因为文件的key是变化的,所以我这里写定一个info字段,
            然后把文件的key写成字符串,然后后台解析字符串,再根据里面的字段获取文件。
            你也可以写其他需要的数据的键值对到FormData里面,一并传到后台,当成一个虚拟form表单用就行了。
            /*
            for(var i= 0,name;i<path.length;i++){
                name = $.md5(path[i].name);
                formData.append(name, path[i]);
                names += name + ',';
            }
            formData.append('info',names);
            $.ajax({
                url: "{{route('upload')}}",
                type: 'POST',
                cache: false,
                data: formData,
                processData: false,
                contentType: false,
                beforeSend: function(){
                    $('#progress_bar').css('color','#1AB394').show();
                },
                success: function(result
                {
                $('#progress_bar').html(result.info).css('color','black').fadeOut(3000,function(){$(this).html('')});
                },
                error: function (result) {

                },
                xhr: function(){
                    var xhr = $.ajaxSettings.xhr();
                   if(onprogress && xhr.upload) {
                        xhr.upload.addEventListener("progress" , onprogress, false);
                        return xhr;
                   }
                }
            });


/*
小tips:在网上查找遇到一些方法(例如function A()),没有详细介绍,不知道总共完整传多少个参数,
每个参数长什么样子的,可以写成function A(a,b,c,d,e,…………){//然后写log打印出来},
这里只有一个event对象参数,所以我写4个形参上去,然后写日志出来,只有第一个参数写出来是一个对象,
而且里面有什么属性也会写出来,后面3个形参则输出为空,
那么这时候就能写定 function A(obj){//只有一个参数,自己写个喜欢的形参名}。
前端后台都能用这个小技巧哦~
*/
function onprogress(evt){   
        console.log(evt);
        var loaded = evt.loaded;
        var tot = evt.total;
        $('#progress_bar').html(Math.floor(100*loaded/tot)+'%');
    }

这里的js是用一个FormData对象,将数据填充进去,然后伪装成从form里提取的数据(意思大概是这个意思吧~),如果要上传文件,那么和普通的ajax传数据的参数有些不同,可以按照我上面写的设置参数,ajax具体参数有什么作用可以看我这个blog:http://blog.csdn.net/qq_29238009/article/details/77506048
因为原生ajax是有进度的参数的,progress还是什么来着,但是jQuery是封装了原生ajax对象的一种对象,是没有设置这个参数的,所以不能像success、error这样直接写函数。但是jQuery有个参数xhr能够返回原生ajax对象,然后通过原生ajax对象进行进度条的操作,如上ajax写好xhr以及它所调用的onprogress函数,就能获取ajax上传的数据进度了。
效果
写好前后台后上传大概就是这个效果了。
input的文件改变的时候写一下ul列表,然后上传的时候写一下进度百分比。当然这些都是可以按需调整的,我这里简单写写,可以设计一下写的更漂亮丰富,加多点特效,写成进度条之类的,也可以删减不要

    后台我写过一个blog,因为前端是js,但是后台可以是不同语言,我这里用的后台是laravel框架,用php写的,如果你是用其他语言写的后台,可以自己写过一个后台适配这个前端。反正就是ajax传一些文件和字段到后台而已,接收好就行了,该怎么处理看自己的业务逻辑需要怎么做吧。

————————————————————————————————————————
laravel后端篇的blog:http://blog.csdn.net/qq_29238009/article/details/77651289

已知缺陷:
1. 和我前言说的那种N个文件用N个input相比,这样的多选上传只能选中同一级目录下的文件(当然这个也是能解决的,因为FormData能模拟表单,所以你可以在页面上随意不同位置写上input然后填充进FormData里面,同样不用form标签包裹住,也能显示上传进度。总的来说,要上传N个级目录下的文件,就要有N个input,同一级目录上传文件就一个input可以了)

  • 0
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值