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实战之文件上传

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

  • Web 安全实战:文件上传

    Web 安全实战:文件上传 0x00 概述 在网站的运营过程中,不可避免地要对网站的某些页面或内容进行更新,这时便...

  • 前端开发—QQ邮箱等文件上传实战技术分享

    web前端开发—QQ邮箱等文件上传实战技术分享 我们最常见的是QQ邮箱及QQ空间需要上传文件及相片,现在小编就教你...

  • win与mac上传文件操作

    mac上传文件到web页面使用PyUserInput库下的PyKeyboard键盘操作类 win上传文件到web页面

  • web安全(五)上传漏洞(一)

    只要web应用程序允许上传文件就有可能存在文件上传漏洞。那么如何确认web应用程序是否存在上传漏洞?比如:我...

  • Golang Web学习(15)—— 文件上传

    本文为转载,原文:Golang Web学习(15)—— 文件上传 介绍 在web开发中,对于文件上传的处理是不可避...

  • 文件上传下载接口

    文件上传下载接口 文件上传 首先确保你引入了 web starter 配置文件上传大小限制 编写控制层传文件 文件...

  • Java Web文件上传展示进度

    1、文件上传演示准备 接前面“Java Web中的文件上传和下载” 为了演示文件上传,先新增一个用于接收文件上传的...

  • 文件的上传

    web.XML配置 多文件上传

  • Web文件上传

    以前博客 学习文件上传笔记,在github上看见一个文件上传练习平台,自己搭一个平台练习。 准备 下载文件git ...

网友评论

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

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