记录:关于Drag&Drop Upload

    虽然google gears已经停止开发了,但是依旧没有退出浏览器,加上现在的html5 Binary,支持拖拽上传的浏览器其实已经不少了,各大互联网公司也都用在了实际的项目上,光是邮箱就有gmail,qq邮箱,163等一线邮箱产品在现代浏览器上都实现了拖拽上传。

    前一阵我看园子里的朋友 jelle 就发了篇拖拽上传的文。我也好奇,拉下来看了看。-- google gears 和 html5 Binary  : )

    所以就拿他的代码稍微改了改,就当是转载, 原文在http://www.cnblogs.com/idche/archive/2010/11/24/1886482.html 

    另外也当自己记录吧,稍微封装了一下下,不完善而且还有bug,配置里面没有对上传文件大小和后缀名的限制接口。

    唉..先不管了,先放这里,以后要用的时候再改改,添点东西

/*
 * drag - drop to upload file
 * by hongru.chenhr[at]gmail.com 
 * at 2011.04.21
 
*/
 
(
function  () {
    
//  private methods
     var  _  =  {
        extend: 
function  (target, source, overwrite) {
            
if  (overwrite  ==  undefined) overwrite  =   true ;
            
for  ( var  p  in  source) {
                
if  ( ! (p  in  target)  ||  overwrite) {
                    target[p] 
=  source[p]
                }
            }
            
return  target;
        },
        log: 
function  (msg, cat) {
            
!! window.console  &&  console[(cat  ?  cat :  ' debug ' )](msg);
        },
        addEvent: 
function  (o, e, f) {
            o.addEventListener 
?  o.addEventListener(e, f,  false ) : o.attachEvent( ' on ' + e,  function  () {f.call(o)});
        }
    }
    
    
//  main function
     var  DDUpload  =   function  (config) {
        
this .setConfig(config);
        
this .init();
    }
    _.extend(DDUpload.prototype, {
        setConfig: 
function  (config) {
            
this .config  =  {
                name: 
' yourFileName ' ,
                action: 
' yourAction ' ,
                target: window,
                
                onloadstart: 
function  () {},
                onprogress: 
function  (e) {},
                oncomplete: 
function  (response) {}
            }
            _.extend(
this .config, config  ||  {});
        },
        init: 
function  () {
            
var  c  =   this .config, _this  =   this ;
            
//  prevent default of dragenter and dragover
            _.addEvent(window,  ' dragenter ' this .preventDefault);
            _.addEvent(window, 
' dragover ' this .preventDefault);
            
            
if  ( !! window.google  &&  google.gears) {
                
/*  google.gears
                 * http://code.google.com/intl/zh-CN/apis/gears/api_httprequest.html
                 
*/  
                
this .xhr  =  google.gears.factory.create( ' beta.httprequest ' );
                _.addEvent(c.target, 
' drop ' function  (e) {
                    _this.googleGears(e);
                })
            } 
else   if  ( !! XMLHttpRequest  &&   !! new  XMLHttpRequest().sendAsBinary) {
                
//  html5 XMLHttpRequest
                 this .xhr  =  window.ActiveXObject  ?   new  window.ActiveXObject( ' Microsoft.XMLHTTP ' ) :  new  XMLHttpRequest();
                _.addEvent(c.target, 
' drop ' function  (e) {
                    _this.html5Binary(e);
                })
            }
        },
        preventDefault: 
function  (e) {
            e 
=  e  ||  window.event;
            
            
if  (e  &&  e.stopPropagation) e.stopPropagation();
            
else  e.cancelBubble  =   true ;
            
            
if  (e  &&  e.preventDefault) e.preventDefault();
            
else  e.returnValue  =   false ;
        },
        googleGears: 
function  (e) {
            
this .preventDefault(e);
            
var  _this  =   this ;
            
try  {
                
var  desktop  =  google.gears.factory.create( ' beta.desktop ' ),
                    data 
=  desktop.getDragData(e,  ' application/x-gears-files ' ),
                    file 
=  data.files[ 0 ];

                
var  d  =   this .googleBuild(file);
                
                
this .xhr.onloadstart  =   this .config.onloadstart;
                
this .xhr.upload.onprogress  =   this .config.onprogress;
                
this .xhr.onreadystatechange  =   function  () {
                    
if  (_this.xhr.readyState  ===   4 ) {
                        _this.config.oncomplete.call(_this, _this.xhr.responseText);
                    }
                }
                
                
this .xhr.open( " POST " this .config.action);
                
this .xhr.setRequestHeader( ' content-type ' ' multipart/form-data; boundary= '   +  d.boundary);
                
this .xhr.send(d.builder.getAsBlob());
                
// this.xhr.onloadstart(file);
                
            } 
catch (e) {
                
            }
        },
        googleBuild: 
function  (file) {

            
var  boundary  =   ' --multipartformboundary '   +  ( + new  Date),
                dashdash 
=   ' -- ' ,
                crlf     
=   ' \n ' ;
            
            
var  builder  =  google.gears.factory.create( ' beta.blobbuilder ' );
        
            builder.append(dashdash);
            builder.append(boundary);
            builder.append(crlf);
            
            builder.append(
' Content-Disposition: form-data; name=" ' +   this .config.name  + ' " ' );
            
if  (file.name) {
                builder.append(
' ; filename=" '   +  file.name  +   ' " ' );
            }
            builder.append(crlf);
            
            builder.append(
' Content-Type: application/octet-stream ' );
            builder.append(crlf);
            builder.append(crlf); 
            
            
/*  Append binary data.  */
            builder.append(file.blob);
            builder.append(crlf);
    
            
/*  Write boundary.  */
            builder.append(dashdash);
            builder.append(boundary);
            builder.append(crlf); 
            
            
/*  Mark end of the request.  */
            builder.append(dashdash);
            builder.append(boundary);
            builder.append(dashdash);
            builder.append(crlf);
            
            
return  {
                builder: builder,
                boundary: boundary
            }
        },
        
        
/*  ====== for html5Binary =======  */
        html5Binary: 
function  (e) {
            
var  _this  =   this ;
            
if  (e.dataTransfer.files.length  ==   0 return ;
            
            
this .preventDefault(e);
            
var  file  =  e.dataTransfer.files[ 0 ];
            
            
var  b  =   this .binaryBuild(file.name, file.getAsBinary());
            
            
this .xhr.onloadstart  =   this .config.onloadstart;
            
this .xhr.onuploadprogress  =   this .config.onprogress;
            
this .xhr.onreadystatechange  =   function  () {
                
if  (_this.xhr.readyState  ===   4 ) {
                    _this.config.oncomplete.call(_this, _this.xhr.responseText);
                }
            }
            
            
this .xhr.open( ' POST ' this .config.action,  true );
            
this .xhr.setRequestHeader( ' content-type ' ' multipart/form-data; boundary= '   +  b.boundary);
            
this .xhr.setRequestHeader( ' Content-Length ' , file.size); 
            
this .xhr.overrideMimeType( ' text/plain; charset=x-user-defined-binary ' );         // read.readAsDataURL(file);
             this .xhr.sendAsBinary(b.builder);
        },
        binaryBuild: 
function  (name, binary) {
            
var  boundary  =   ' --fileupload ' + ( + new  Date),
                dashdash 
=   ' -- ' ,
                crlf 
=   ' \n ' ;
                
            
var  builder  =   '' ;
         
            builder 
+=  dashdash;
            builder 
+=  boundary;
            builder 
+=  crlf;
            
            
/*  httprequest header  */
            builder 
+=   ' Content-Disposition: form-data; name=" ' +   this .config.name  + ' " ' ;
            
if  (name) {
              builder 
+=   ' ; filename=" '   +  encodeURIComponent(name)  +   ' " ' ;
            }
            builder 
+=  crlf;
         
            builder 
+=   ' Content-Type: application/octet-stream ' ;
            builder 
+=  crlf;
            builder 
+=  crlf; 
            
            
/*  build Binary data  */
            builder 
+=  binary;
            builder 
+=  crlf;
            
            
/*  Write boundary.  */
            builder 
+=  dashdash;
            builder 
+=  boundary;
            builder 
+=  crlf;
            
            
/*  Mark end of the request.  */
            builder 
+=  dashdash;
            builder 
+=  boundary;
            builder 
+=  dashdash;
            builder 
+=  crlf;
            
            
return  {
                builder: builder,
                boundary: boundary
            }
        }
    })
    
    
this .DDUpload  =  DDUpload;
    
})(); 

  

    比较惊讶的一点是http 请求头的创建,格式还真奇怪,非要 -- 和换行结合,且不像js一样支持分号... 汗,算我少见多怪吧... 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值