基于jquery的多文件上传

Posted 木极子

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了基于jquery的多文件上传相关的知识,希望对你有一定的参考价值。

1、文件上传前台设计

说到前台设计,还真的有些不知道怎么讲好,还是老样子,直接上图来的直接,在此也说明下:本人不擅长做PS,所以很多素材(图片)都是网上寻找的,这个上传程序可以上传各种文件,至于哪些?我没数过,我不介意你数一数,我就用简单的图片上传来演示吧,附带预览功能。

还没有上传的时候的界面(有点丑,莫嫌弃)

要开始上传时:

这个时候鼠标上移的时候,可以对文件进行操作(删除掉误选的照片和查看文件名)


上传时的图片(由于本人是用js模拟上传,所以上面的总的进度条不会动,完整的程序完全没有问题):

2、代码讲解

前台界面,我还是很简单,就一个div,div中带一个id,如下所示:

<div id="imgUpload"></div>

需要的插件也只有一个jquery

<script type="text/javascript" src="js/jquery-2.2.1.min.js"></script>

怎么执行呢?我全都封装好了,就下面简单的一句代码:

 $("#imgUpload").initUpload({
        "url":"servlet/ProgressUploadServlet",
        "selectBTText":"选择图片",
       // "fileType":"image/*",
        "size":"10"
    });

附带说明一份:也是这个程序主要功能的表现吧

initUpload参数对象说明:
参数        是否必须      默认值                                                                作用
url           可选        默认“servlet/ProgressUploadServlet”                              上传后台服务接口
selectBTText  可选        选择文件                                                         选择文件上传按钮的信息
fileType      可选        (所有文件)参考:http://www.cnblogs.com/Joans/p/3158582.html        设置文件上传的格式
size          可选        不限定                                                             文件(单个)大小,单位MB

至于CSS似乎没什么好讲的,如果感兴趣可以下载源代码,什么都有了,呵呵

至于js,重要的说明一下:

首先了解下选择多个文件:也很简单,用html标签就能实现了

<input type="file" id="input"  multiple="multiple"> 
当然我点击的是按钮,稍微懂一点的就知道怎么实现了,无非就是用js创建了个inpit模拟点击下。
/**
 *  zxm
 * 作用:点击按钮可以弹出一个对话框,选择文件
 * @param uploadId 上传文件的id
 */
function selectFile(uploadId){
    var inputObj=document.createElement('input');
    inputObj.setAttribute('id',uploadId+'_file');
    inputObj.setAttribute('type','file');
    inputObj.setAttribute("style",'visibility:hidden');
    inputObj.setAttribute("multiple","multiple");
    inputObj.setAttribute("onchange","showFile(this.files,'"+uploadId+"')");//这句很重要,文件选择的时候就会触发这个事件
    var opt=$("#"+uploadId).data("opt");
    if(opt.fileType){
        inputObj.setAttribute("accept",opt.fileType);
    }
    document.body.appendChild(inputObj);
    inputObj.click();
    $("#"+opt.uploadId).removeData("FileArray");
    var FileArray = new Array();
    $("#"+opt.uploadId).data("FileArray",FileArray);
}
选择了文件后做什么,当然是显示出来:如果是图片就预览,如果是其他格式的文件就选择相应的图片显示出来,代码如下:

/**
 * zxm
 * 作用:显示缩略图
 * @param files 文件列表
 * @param uploadId  文件提交的功能id,也就是初始化的id
 */
function showFile(files,uploadId){
    var imgtest=/image\\/(\\w)*/;  //验证图片格式
    var audiotest = /audio\\/(\\w)*/; //验证音乐
    var videotest =/video\\/(\\w)*/; //视频验证
    var pdftest = /application\\/pdf/; //pdf验证
    var ziptest = /application\\/(zip|rar|7z|cab|iso)/; //压缩验证
    var opt=$("#"+uploadId).data("opt");

    if(window.FileReader){
        $("#"+uploadId+"_Context").html("");
        for(var i =0; i<files.length;i++) {
            var file = files[i];
           if(opt.size!=""){
                if(file.size>(opt.size)*1048576){
                    alert("文件"+file.name+",太大不提供上传");
                    continue;
                }
           }
            var reader = new FileReader();
            reader.readAsDataURL(file);
            reader.onload = (function (f,i,uploadId) {
                var FileArray=$("#"+uploadId).data("FileArray");
                FileArray[FileArray.length]=i;
                $("#"+uploadId).data("FileArray",FileArray);
                return function(e){
                    var result = e.target.result;
                    var appendData = "";
                    if(imgtest.test(file.type))
                    {
                        appendData += "<div class='showItemDiv' id='" + uploadId + "_showItemDiv_" + i + "' style='background-image: url(" + result + ");' οnmοuseοver=showItemTitleStatus('" + i + "','true','" + uploadId + "') οnmοuseοut=showItemTitleStatus('" + i + "','false','" + uploadId + "')>";
                    }else if(audiotest.test(file.type)){
                        appendData += "<div class='showItemDiv' id='" + uploadId + "_showItemDiv_" + i + "' style='background-image: url(images/filetype/MUISIC.png);background-repeat: no-repeat;' οnmοuseοver=showItemTitleStatus('" + i + "','true','" + uploadId + "') οnmοuseοut=showItemTitleStatus('" + i + "','false','" + uploadId + "')>";
                    }else if(videotest.test(file.type)){
                        appendData += "<div class='showItemDiv' id='" + uploadId + "_showItemDiv_" + i + "' style='background-image: url(images/filetype/AVI.png);background-repeat: no-repeat;' οnmοuseοver=showItemTitleStatus('" + i + "','true','" + uploadId + "') οnmοuseοut=showItemTitleStatus('" + i + "','false','" + uploadId + "')>";
                    }else if(pdftest.test(file.type)){
                        appendData += "<div class='showItemDiv' id='" + uploadId + "_showItemDiv_" + i + "' style='background-image: url(images/filetype/PDF.png);background-repeat: no-repeat;' οnmοuseοver=showItemTitleStatus('" + i + "','true','" + uploadId + "') οnmοuseοut=showItemTitleStatus('" + i + "','false','" + uploadId + "')>";
                    }else if(ziptest.test(file.type)){
                        appendData += "<div class='showItemDiv' id='" + uploadId + "_showItemDiv_" + i + "' style='background-image: url(images/filetype/ZIP.png);background-repeat: no-repeat;' οnmοuseοver=showItemTitleStatus('" + i + "','true','" + uploadId + "') οnmοuseοut=showItemTitleStatus('" + i + "','false','" + uploadId + "')>";
                    }else{
                        appendData += "<div class='showItemDiv' id='" + uploadId + "_showItemDiv_" + i + "' style='background-image: url(images/filetype/FILE.png);background-repeat: no-repeat;' οnmοuseοver=showItemTitleStatus('" + i + "','true','" + uploadId + "') οnmοuseοut=showItemTitleStatus('" + i + "','false','" + uploadId + "')>";
                    }
                    //下面是关于删除和确认按钮
                    appendData +="<div class='showItemStatus' id='"+uploadId+"_showItemStatus_"+i+"' >";
                    appendData +="<img src='images/x_alt.png' id='"+uploadId+"_showItemStatus_img_"+i+"' οnclick=removeFile('"+i+"','"+uploadId+"')>";
                    appendData +="</div>";


                    //下面是关于文件名
                    appendData += "<div class='fileNameDiv'id='"+uploadId+"_showItem_file_name_"+i+"'>" + f.name + "</div>";

                    //这一条是进度条
                    appendData+="<div class='prograssbar' ><div class='prograssbar_inner' id='"+uploadId+"_showItem_prograssbar_"+i+"'></div></div>";
                    appendData += "</div>";
                    $("#" + uploadId + "_Context").append(appendData);

                }
            })(file,i,uploadId);
        }
        var contentDiv="<div class='uploadBTDiv' >";
        contentDiv+="<div class='prograssbarsummer'>";
        contentDiv+="<div class='prograssbar_inner prograssbarsummer_inner' ></div>";
        contentDiv+="<div class='prograssbar_number'></div>";
        contentDiv+="</div>";
        contentDiv+="<div class='prograssbarsummer_message'>";
        contentDiv+="<span class='prograssbar_size'></span><span class='prograssbar_useTime'></span><span class='prograssbar_needTime'></span><span class='prograssbar_velocity'></span>"
        contentDiv+="</div>";

        contentDiv+="<div>";
        contentDiv+="<button class='uploadBT' id='"+uploadId+"_uploadBt' οnclick=uploadFile('"+uploadId+"')>上传</button>";
        contentDiv+="<button id='"+uploadId+"_canceldBt' class='cancelBT' οnclick=cancelFile('"+uploadId+"')>取消</button>";
        contentDiv+="<button id='"+uploadId+"_cleanBt' class='cleanBT' οnclick=cleanFile('"+uploadId+"')>清空</button>" ;
        contentDiv+="</div>";
        contentDiv+="</div>";
        $("#"+uploadId+"_Context").append(contentDiv);
    }else{
        alert("您的浏览器不支持缩略图的显示");
    }
}

这里有一个稍微有趣的东西FileReader,我也稍微讲解下:

它的作用很简单,就一个“读取文件”,稍微专业点的话就是:FileReader对象让Web应用程序的异步读取文件内容(或原始数据缓冲区)存储在用户的计算机上,使用文件或BLOB对象指定要读取的文件或数据。

FileReader有五种读取的方法:

  1. abort()  终端读取
  2. readAsBinaryString() 返回文件内容的二进制格式(不推荐使用)
  3. readAsArrayBuffer()  返回文件内容的 ArrayBuffer 格式(图片文件推荐使用)
  4. readAsDataURL()   返回文件内容的 data URL格式
  5. readAsText() 返回文件内容的纯文本格式

同时这个FileReader还带有一些事件,这些时间也简单,为了方便理解,我也写了一个小小的测的测试文件,看下面:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>js文件操作教程</title>
</head>
<body>
<div id="filecontent"></div>
<h3>案例1:以text格式输出</h3>
    选择文件<input type="file" οnchange="showFilesAsText(this.files)"/>
<h3>案例2:以URL格式输出</h3>
    选择文件<input type="file" οnchange="showFilesAsDataURL(this.files)"/>
<h3>案例3:以二进制格式输出</h3>
    选择文件<input type="file" οnchange="showFilesAsBinaryString(this.files)"/>
<!--说明:FileReader有5个方法:
            1、readAsText() – 返回文件内容的纯文本格式
            2、readAsBinaryString() –返回文件内容的二进制格式 (不推荐– 推荐使用 readAsArrayBuffer())
            3、readAsDataURL() – 返回文件内容的 data URL格式
            4、abort 终端读取

            **读取的结果从 event.target.result 获取。

            文件读取成功则执行 onload 方法否则执行 onerror 方法

            事件:
            1、onabort 中断
            2、onerror 出错
            3、onloadstart 开始
            4、onprogress 正在读取
            5、onload 成功读取
            6、onloadend 读取结束,无论是否成功
 -->


</body>
</html>

<script type="text/javascript">
    function showFilesAsText(files){
        //如果文件数量不为0
        if(files.length){
            var file = files[0];
            var reader = new FileReader();
            reader.onload = function(e){
                document.getElementById("filecontent").innerHTML = e.target.result;
            }
            reader.readAsText(file);
        }
    }

    function showFilesAsDataURL(files){
        if(files.length){
            var file = files[0];
            var reader = new FileReader();
            reader.readAsDataURL(file);
            reader.οnlοad=function(e){
                document.getElementById("filecontent").innerHTML ="<img src='" +e.target.result+"'/>";
            }
        }
    }

    function showFilesAsBinaryString(files){
        if(files.length){
            var file = files[0];
            var reader = new FileReader();
            reader.readAsBinaryString(file);
            reader.οnlοad=function(e){
                document.getElementById("filecontent").innerHTML = e.target.result;
            }
        }
    }
</script>
还有个详细的介绍,可以读一读:https://developer.mozilla.org/en-US/docs/Web/API/FileReader

要显示文件上面好几种方式都可以实现,为了方便起见用了readAsDataURL()这个方法。


然后了解下formData()

var formData = new FormData();
它其实也没什么神秘,它呢一个HTML <form>元素指定的表单时,对象将被填充形式的键/值。它还将编码文件输入内容。 注意:它还将编码文件输入内容

如果想知道详情,看看这个链接吧:https://developer.mozilla.org/en-US/docs/Web/API/FormData/FormData

so 我就能用了这个玩意,装了些我要上传的文件

至于上传,我自然是选择jquery上传,看下面的代码:

$.ajax({
        type:"post",
        url:url,
        data:formData,
        processData : false,
        contentType : false,
        success:function(data){
            //alert(data);
        },
        error:function(e){
            //alert("文件上传失败");
        }
    })
注意有两个很重要的属性
 processData : false,

contentType : false,
这两个一定要写,至于有什么用,查一下jquery文档就知道了

好了,主要的东西也就这么点,其它就是数据的获取,以及效果的显示问题了,如果感兴趣可以看源代码,如果有什么好的想法或者建议,也可以和我交流

前台js测试源代码地址:http://pan.baidu.com/s/1eRGPoUe

后台程序完整代码(java):http://pan.baidu.com/s/1kVAjGaV







以上是关于基于jquery的多文件上传的主要内容,如果未能解决你的问题,请参考以下文章

(27) java web的struts2框架的使用-基于表单的多文件上传

MultipartFile文件上传问题

基于file上传文件的并发上传(多个文件一起上传到后台并把数据存储的同一条数据中,如 数据库字段videopath,imge。前台发送来的文件file1,file2。 videopath=file1,

ajax上传文件 基于jquery form表单上传文件

什么是最好的多文件 JavaScript / Flash 文件上传器?

基于.NET Core + Jquery实现文件断点分片上传