HTML5托拽上传(XMLHttpRequest和Google Gears)

      HTML5的拖拽上传功能可拆分为两个部分实现,一个是对象的拖拽功能,另一个是上传功能。拖拽功能的实现基于HTML5 DOM对象的拖拽事件 ,FF3.6+和Chrome7+都实现了该功能,所以不用做特别的兼容,代码如下:

 
拖拽功能代码
    var uploadZone=$("uploadZone"),
        iptFile,
        file,
        ffUpload
=new FirefoxFileUpload("http://localhost/upload/a.php"); 
        
//chromeUpload=new ChromeFileUpload("http://localhost/upload/a.php");
        
    
function focus(state){
        uploadZone.style.backgroundColor
=state?"#f0ab0c":"";
    }



    uploadZone.addEventListener(
"dragenter",function(e){
        focus(
true);
        e.stopPropagation();
        e.preventDefault();
    },
false);

    uploadZone.addEventListener(
"dragleave",function(e){
        focus(
false);

    },
false);

    uploadZone.addEventListener(
"dragover",function(e){
        e.stopPropagation();
        e.preventDefault();
    },
false);

    uploadZone.addEventListener(
"drop",function(e){
        e.stopPropagation();
        e.preventDefault();
        focus(
false);
        
        
//Firefox上传
        ffUpload.xhr.upload.onprogress=function(e){
            
var w=$("pgBorder").offsetWidth;
            
            $(
"progress").style.width=e.loaded/e.total*w+"px";
        };
        ffUpload.xhr.upload.onload
=function(){
            $(
"progress").style.width=$("pgBorder").offsetWidth+"px";
        };
        ffUpload.upload(ffUpload.getFile(e));

        
        
//Chrome上传
    //    chromeUpload.xhr.upload.onprogress=function(e){
    //        console.log(e.loaded/e.total*100+"%");
    //    };
    //    chromeUpload.upload(chromeUpload.getFile(e));
        
    },
false);

而HTML5的文件传输功能则是基于两套实现方式:
    firefox:
        fileReader.readAsBinaryString 读取二进制串
        XMLHttpRequest.sendAsBinary 以二进制的格式发送给服务器端(真给力)
    
    chrome:
        gears API

因为XMLHttpRequest.sendAsBinary目前还没有被w3c列为标准,所以只能在Firefox中私有地使用。

以下是简单封装的两个浏览器的上传类
      
Firefox 上传类
 var FirefoxFileUpload=function(url,dataName){
                
this.xhr=new XMLHttpRequest();
                
                
this.__file=null;
                
this.__fileReader=new FileReader();
                
this.__url=url;
                
this.__dataName=dataName || "FileData";
                
                
this.__initReader();
            };
            FirefoxFileUpload.prototype
={
                upload:
function(file){
                    
if(!file){
                        
return;
                    }
                    
                    
this.__file=file;
                    
this.__fileReader.readAsBinaryString(this.__file);
                },
                
                getFile:
function(e){
                    
return e.dataTransfer.files[0];
                },
                
                __send:
function(){
                    
var xhr=this.xhr,
                        boundary
="----------BOUNDARY"+(new Date()).getTime(),
                        body
=this.__getBody(this.__fileReader.result,boundary);
                    
                    xhr.open(
"post",this.__url,true);
                    xhr.setRequestHeader(
"Content-Type","multipart/form-data, boundary="+boundary);
                    xhr.setRequestHeader(
"Content-Length",this.__file.size);

                    xhr.sendAsBinary(body);
                },
                
                __initReader:
function(){
                    
var me=this;
                    
this.__fileReader.addEventListener("load",function(){
                        me.__send();
                    },
false);
                },
                
                __getBody:
function(readerResult,boundary){
                    
return ['--',boundary,'\r\n',
                            
'content-disposition: form-data; name="',this.__dataName,'"; filename="',encodeURI(this.__file.name),'"\r\n',
                            
'Content-Type: ',this.__file.type,'\r\n\r\n',
                             readerResult,
"\r\n",
                            
'--',boundary,'--\r\n'
                        ].join(
"");
                }
                
            };

Chrome 上传类
var ChromeFileUpload=function(url,dataName){
                
this.xhr=google.gears.factory.create("beta.httprequest");
                
                
this.__url=url;
                
this.__file=null;
                
this.__builder=google.gears.factory.create("beta.blobbuilder");
                
this.__dataName=dataName || "FileData";
            };
            ChromeFileUpload.prototype
={
                upload:
function(file){
                    
this.__file=file;
                    
this.__send();
                },
                
                getFile:
function(e){
                    
var desktop=google.gears.factory.create("beta.desktop");
                    
return desktop.getDragData(e,"application/x-gears-files").files[0];
                },
                
                __send:
function(){
                    
var xhr=this.xhr,
                        boundary
="----------BOUNDARY"+(new Date()).getTime();
                    
                    xhr.open(
"post",this.__url,true);
                    xhr.setRequestHeader(
"Content-Type","multipart/form-data, boundary="+boundary);
                    
                    
this.__updateBuilder(boundary);
                    xhr.send(
this.__builder.getAsBlob());
                },
                
                __updateBuilder:
function(boundary){
                    
var bdr=this.__builder;
                    
                    bdr.append([
'--',boundary,'\r\n',
                                
'content-disposition: form-data; name="',this.__dataName,'"; filename="',encodeURI(this.__file.name),'"\r\n',
                                
'Content-Type: ',this.__file.type,'\r\n\r\n'].join(""));
                    bdr.append(
this.__file.blob);
                    bdr.append([
"\r\n",
                                
'--',boundary,'--\r\n'
                                ].join(
""));
                }
            };

两种上传方式都是用的基于表单的文件传输协议 RFC-1867  (RFC-1867 中文版)。

这两个类配合前面的拖拽代码即可实现HTML5版的拖拽上传。。。。。有了标准才是真的方便啊。。。。

posted @ 2011-02-28 20:34  随机  阅读(2586)  评论(0编辑  收藏  举报