叶落为重生每片落下的叶子都是为了下一次的涅槃...^_^

记录:关于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 == 0return;
            
            
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一样支持分号... 汗,算我少见多怪吧... 

posted on 2011-04-28 15:09  岑安  阅读(1019)  评论(0编辑  收藏  举报

导航