Web实战之文件上传

作者: suemi | 来源:发表于2014-12-10 12:30 被阅读97次

    前言

    由于讨厌各种上传插件和UI绑定,同样是为了自己练练手,我写了一个十分小巧的jQuery上传插件——JFile

    [文档]()

    提供的功能

    • 多文件上传
    • 中途取消
    • 文件大小、类型限制设定
    • 能取到进度(进度条UI可以自己定制哦)
    • 可选的上传图片预览
    • 类似于jQuery AJAX的调用风格

    依赖

    • 上传依赖于FormData和Level2的XHttpRequest(一般都支持)
    • 预览依赖于HTML5的File API
    • jQuery

    使用

    var jq=$('#input').upload(url,{
        preview:true,
        limits:{
            fieldSize:40,
            ...
        },
        ...
    }).done(function(data,status,xhr){..})
      .fail(function(xhr,status,err){..})
      .always(function(xhr,status,err){..})
      .progress(function(percentage){..});
    jq.abort();
    

    源代码

    /**
     * Created by suemi on 14-12-8.
     */
    (function($){
        $.fn.upload=function(url,settings){
    
            var option={
                method:'POST',
                action:url,
                dataType:'json',
                limits:{},
                preview:null
            };
            if(!settings) var settings={};
            $.extend(option,settings);
            var getXhr = function(){
                var xhr;
                return function(){
                    if (xhr) return xhr;
                    if (typeof XMLHttpRequest !== 'undefined') {
                        xhr = new XMLHttpRequest();
                    } else {
                        var v = [
                            "Microsoft.XmlHttp",
                            "MSXML2.XmlHttp.5.0",
                            "MSXML2.XmlHttp.4.0",
                            "MSXML2.XmlHttp.3.0",
                            "MSXML2.XmlHttp.2.0"
                        ];
                        for (var i=0; i < v.length; i++){
                            try {
                                xhr = new ActiveXObject(v[i]);
                                break;
                            } catch (e){}
                        }
                    }
                    return xhr;
                }
            }();
            function checkExtension(dst,src){
                var tmp=dst.split('/');
                if(tmp[0]=='image'){
                    if($.inArray('image/*',src)==-1){
                        if($.inArray(tmp[1],src)==-1) return false;
                        else return true;
                    }
                    else return true;
                }
                else{
                    if($.inArray(tmp[1],src)==-1) return false;
                    else return true;
                }
            }
    
    
    
    
            var fileList=[];
            $(this).each(function(){
                for(var i=0;i<this.files.length;i++){
                    fileList.push(this.files[i]);
                }
            });
            return $.Deferred(function(){
                var xhr=getXhr();
                var defer=this;
                this.abort=function(){
                  if(xhr) xhr.abort();
                  return defer;
                };
                this.preview=function(tmp){
                    for(var i in fileList){
                        var file=fileList[i];
                        if(file.type.split('/')[0]=='image'){
                            if(!window.FileReader){
                                alert('Too old browser, you need a modern one!');
                                return defer;
                            }
                            var reader=new FileReader();
                            reader.name=file.name;
                            reader.onloadend=function(evt){
                                console.log(this.num);
                                if(reader.error) tmp.append($('<p>'+this.name+' fails to be loaded</p>'));
    
                                else tmp.append($('<img>',{'src':evt.target.result,'alt':this.name}));
                            };
                            reader.readAsDataURL(file);
                        }
                        else continue;
                    }
                    return defer;
                };
                if(window.FormData) var form=new FormData();
                else{
                    // alert('Too old for your browser, get a modern one!');
                    this.reject(xhr,null,new Error('Too Old Browser'));
                    return this;
                }
                if(!xhr){
                    this.reject(xhr,null,new Error('Too Old Browser'));
                    return this;
                }
                if(!option.action){
                    this.reject(xhr,null,new Error('URL Needed'));
                    return this;
                }
                xhr.open(option.method,option.action);
                xhr.upload.addEventListener('progress',function(evt){
                    if(evt.lengthComputable){
                        var complete=evt.loaded/evt.total | 0;
                    }
                    defer.notify(complete);
                });
    
                xhr.onreadystatechange=function(){
                    if(this.readyState!==4) return;
                    if(this.status==200){
                        var data;
                        switch(option.dataType){
                            case 'text':
                                data=this.responseText;
                                break;
                            case 'html':
                                data= $.parseHTML(this.responseText);
                                break;
                            case 'xml':
                                data= $.parseXML(this.responseXML);
                                break;
                            case 'json':
                                data= $.parseJSON(this.responseText);
                                break;
                            default :break;
                        }
                        defer.resolve(data,this.status,this);
                    }
                    else{
                        defer.reject(this,this.status,this.responseText);
                    }
                };
                if(fileList.length==0){
                    //defer.reject(xhr,xhr.status,new Error('No File Select'));
                    return defer;
                }
                if(option.limits.fieldSize&&option.limits.fieldSize<fileList.length){
                    var err=new Error('Too Many Files');
                    defer.reject(xhr,xhr.status,err);
                    return defer;
                }
                for(var i in fileList){
                    var file=fileList[i];
                    if(option.limits.validExtension&&!checkExtension(file.type,option.limits.validExtension)){
                        var err=new Error('File Type Error');
                        err.filename=file.name;
                        defer.reject(xhr,xhr.status,err);
                        continue;
                    }
                    if(option.limits.fileSize&&option.limits.fileSize<file.size){
                        var err=new Error('Too Large Size');
                        defer.reject(xhr,xhr.status,err);
                        return defer;
                    }
    
                    if(option.start) option.start(file);
                    form.append(i,file,file.name);
                    if(option.maxSize) option.maxSize-=file.size;
                }
                if(option.preview) this.preview(option.preview);
                xhr.send(form);
                return defer;
            });
        };
    })(jQuery);
    

    相关文章

      网友评论

        本文标题:Web实战之文件上传

        本文链接:https://www.haomeiwen.com/subject/iuyntttx.html