zoukankan      html  css  js  c++  java
  • mass Framework ajax模块

    由于ajax模块要涉及到后台的配合才能看到后台,因此我先给出后台代码,如果会rails的人,可以复制下来搭建相应的运行环境。

    控制器部分

    
    class HomeController < ApplicationController
       skip_before_filter :verify_authenticity_token  
    
      def index
        #如果XMLHttpRequest请求
        if request.xhr?
          respond_to do |format|
            format.json do 
              p "format.json"
              render :json => {
                "aaa"=>"ruby",
                "bbb"=>"louvre",
                "ccc"=>{
                  "ddd"=>Time.now,
                  "eee"=>"司徒正美"
                }
              }
            end
            format.html do 
              render 'home/html_test.erb'
            end
            format.text do
              p "format.text"
              render :text=> "输出纯文本消息"
            end
            format.js do
              p "format.js"
              render :js => "alert('Hello Rails');"
            end        
            format.xml do
              p "format.xml"
              #http://ap.rubyonrails.org/classes/Builder/XmlMarkup.html
              render :template => 'home/test.rxml', :layout => false
            end
          end
        end
      end
      
      def upload
        render :text => "OK"
      end
    
    end
    

    视图部分:

    html_test.erb

    <table class="blue_table">
      <colgroup><col class="grey" width="30%">
      <col class="yellow">
      </colgroup><thead>
        <tr>
          <th colspan="2">javascript相关的小研究心得</th>
        </tr>
      </thead>
      <tbody>
         <tr>
          <td><a href="2009/11/06/1597523.html">获取函数名</a></td>
          <td><a href="2011/01/05/1926226.html">iframe高度自适应</a></td>
       </tr>
          <tr>
          <td><a href="2010/01/20/1652646.html">类型判定</a></td>
          <td><a href="2010/05/25/1742173.html">jsonp跨域</a></td>
       </tr>
       <tr>
          <td><a href="2010/05/18/1738034.html">修复IE6 base bug</a></td>
          <td><a href="2010/04/06/1705817.html">getBasePath函数</a></td>
       </tr>
        <tr>
          <td><a href="2010/04/15/1712780.html">domReady</a></td>
          <td><a href="2009/10/14/1583362.html">判定浏览器</a></td>
        </tr>
        <tr>
          <td><a href="2009/09/24/1572977.html">获取随机颜色</a></td>
          <td><a href="2009/10/14/1583523.html">contains函数</a></td>
        </tr>
        <tr>
          <td><a href="2009/10/30/1593094.html">惰性函数</a></td>
          <td><a href="2009/11/09/1598761.html">currying函数</a></td>
        </tr>
        <tr>
          <td><a href="2009/11/08/1598383.html">字符串的乘法</a></td>
          <td><a href="2009/10/31/1593484.html">javascript 动态解析脚本</a></td>
        </tr>
        <tr>
          <td><a href="2009/11/13/1602122.html">动态this与动态绑定</a></td>
          <td><a href="2009/11/10/1599978.html">forEach函数</a></td>
        </tr>
        <tr>
          <td><a href="2009/07/17/1525637.html">移除DOM节点</a></td>
          <td><a href="2009/07/24/1529640.html">getElementsByClassName</a></td>
        </tr>
        <tr>
          <td><a href="2009/07/24/1530020.html">跨浏览器的事件写法</a></td>
          <td><a href="2009/07/24/1530074.html">javascript的闭包</a></td>
        </tr>
        <tr>
          <td><a href="2009/08/01/1536710.html">iframe元素用法总结</a></td>
          <td><a href="2009/08/08/1541578.html">javascript AOP实现</a></td>
        </tr>
        <tr>
          <td><a href="2009/08/19/1550088.html">JS类写法的性能研究</a></td>
          <td><a href="2009/08/20/1550526.html">javascript 键盘事件总结</a></td>
        </tr>
        <tr>
          <td><a href="2009/08/21/1551270.html">javascript变量的作用域</a></td>
          <td><a href="2009/10/07/1578629.html">动态加载图片与脚本</a></td>
        </tr>
        <tr>
          <td><a href="2009/08/09/1542174.html">javascript事件代理</a></td>
          <td><a href="2009/08/26/1554204.html">javascript的事件加载</a></td>
        </tr>
      <tr>
          <td><a href="2010/01/06/1640148.html">高效地获取XMLhttp对象</a></td>
          <td><a href="2009/08/24/1552862.html">javascript的鼠标事件</a></td>
        </tr>
        <tr>
          <td><a href="2009/07/14/1523104.html">动态添加样式表规则</a> <a href="2009/08/30/1556869.html">2</a></td>
          <td><a href="2010/02/11/1667364.html">自动执行函数</a></td>
        </tr>
        <tr>
          <td><a href="2009/09/05/1559883.html">精确获取样式属性</a> <a href="2009/09/08/1562212.html">2</a></td>
          <td><a href="2009/09/08/1562444.html">精确获取页面元素的位置</a></td>
        </tr>
        <tr>
          <td><a href="2010/02/11/1667364.html">自动执行函数</a></td>
          <td><a href="2009/07/24/1530020.html">事件兼容</a></td>
        </tr>
       <tr>
          <td><a href="2009/09/16/1566699.html">缓动效果</a> <a href="2009/09/17/1567607.html">2</a></td>
          <td><a href="2009/10/01/1577219.html">无缝滚动</a> <a href="2009/10/03/1577735.html">2</a></td>
        </tr>
        <tr>
          <td><a href="2009/09/30/1576699.html">javascript图片轮换</a> <a href="2009/10/06/1578289.html">2</a></td>
          <td>
            <a href="2009/10/09/1578966.html">javascript线性渐变</a> 
            <a href="2009/10/10/1580061.html">2</a> 
            <a href="2009/10/14/1582876.html">3</a> 
        </td>
        </tr>
      </tbody>
    </table>
    

    test.rxml

    
    xml = Builder::XmlMarkup.new
    xml.instruct!                   # 
    xml.html {                      # 
      xml.head {                    #   
        xml.title("History")        #     History
      }                            #   
      xml.body {                    #   
        xml.comment! "HI"           #     
        xml.h1("Header")            #     

    Header

    xml.p("paragraph") #

    paragraph

    } # }

    路由配置

      map.resources  :homes, :member => {:upload => :post }
      map.home '' ,:controller => 'home',:action => 'index'
    

    ajax模块源码:

    //数据请求模块
    (function(global,DOC){
        var dom = global[DOC.URL.replace(/(#.+|\W)/g,'')];
        dom.define("ajax","node,emitter", function(){
            dom.log("已加载ajax模块");
            var r20 = /%20/g,
            rCRLF = /\r?\n/g,
            encode = global.encodeURIComponent,
            rheaders = /^(.*?):[ \t]*([^\r\n]*)\r?$/mg, // IE leaves an \r character at EOL
            rlocalProtocol = /^(?:about|app|app\-storage|.+\-extension|file|res|widget):$/,
            rnoContent = /^(?:GET|HEAD)$/,
            rquery = /\?/,
            rurl = /^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+))?)?/,
            // Document location
            ajaxLocation
            // #8138, IE may throw an exception when accessing
            // a field from window.location if document.domain has been set
            try {
                ajaxLocation = global.location.href;
            } catch( e ) {
                // Use the href attribute of an A element
                // since IE will modify it given document.location
                ajaxLocation = DOC.createElement( "a" );
                ajaxLocation.href = "";
                ajaxLocation = ajaxLocation.href;
            }
    
            // Segment location into parts
            var ajaxLocParts = rurl.exec( ajaxLocation.toLowerCase() ) || [],
            transports = { },//传送器
            converters ={//转换器
                text: function(dummyXHR,text,xml){
                    return text != undefined ? text : ("xml" in xml ?  xml.xml: new XMLSerializer().serializeToString(xml));
                },
                xml : function(dummyXHR,text,xml){
                    return xml != undefined ? xml : dom.parseXML(text);
                },
                html : function(dummyXHR,text,xml){
                    return  dom.parseHTML(text);
                },
                json : function(dummyXHR,text,xml){
                    return  dom.parseJSON(text);
                },
                script: function(dummyXHR,text,xml){
                    dom.globalEval(text);
                }
            },
            accepts  = {
                xml: "application/xml, text/xml",
                html: "text/html",
                text: "text/plain",
                json: "application/json, text/javascript",
                script: "text/javascript, application/javascript, application/ecmascript, application/x-ecmascript",
                "*": "*/*"
            },
            defaultOptions = {
                type:"GET",
                contentType: "application/x-www-form-urlencoded; charset=UTF-8",
                async:true,
                dataType:"text",
                jsonp: "callback"
            };
    
            function normalizeOptions(o) {
                // deep mix
                o = dom.Object.merge.call( {},defaultOptions, o);
                //判定是否跨域
                if (o.crossDomain == null) {
                    var parts = rurl.exec(o.url.toLowerCase());
                    o.crossDomain = !!( parts &&
                        ( parts[ 1 ] != ajaxLocParts[ 1 ] || parts[ 2 ] != ajaxLocParts[ 2 ] ||
                            ( parts[ 3 ] || ( parts[ 1 ] === "http:" ?  80 : 443 ) )
                            !=
                            ( ajaxLocParts[ 3 ] || ( ajaxLocParts[ 1 ] === "http:" ?  80 : 443 ) ) )
                        );
                }
                //转换data为一个字符串
                if ( o.data && o.data !== "string") {
                    o.data = dom.param( o.data );
                }
                //type必须为大写
                o.type = o.type.toUpperCase();
                o.hasContent = !rnoContent.test(o.type);
    
                if (!o.hasContent) {//如果为GET请求,则参数依附于url上
                    if (o.data) {
                        o.url += (rquery.test(o.url) ? "&" : "?" ) + o.data;
                    }
                    if (o.cache === false) {
                        o.url += (rquery.test(o.url) ? "&" : "?" ) + "_time=" + Date.now();
                    }
                }
                return o;
            }
    
            "get post".replace(dom.rword,function(method){
                dom[ method ] = function( url, data, callback, type ) {
                    // shift arguments if data argument was omitted
                    if ( dom.isFunction( data ) ) {
                        type = type || callback;
                        callback = data;
                        data = undefined;
                    }
                    return dom.ajax({
                        type: method,
                        url: url,
                        data: data,
                        success: callback,
                        dataType: type
                    });
                };
    
            });
    
            dom.mix(dom,{
                getScript: function( url, callback ) {
                    return dom.get( url, null, callback, "script" );
                },
    
                getJSON: function( url, data, callback ) {
                    return dom.get( url, data, callback, "json" );
                },
                upload: function(url, form, data, callback, dataType) {
                    if (dom.isFunction(data)) {
                        dataType = callback;
                        callback = data;
                        data = undefined;
                    }
                    return dom.ajax({
                        url:url,
                        type:'post',
                        dataType:dataType,
                        form:form,
                        data:data,
                        success:callback
                    });
                },
                serialize : function(form) {
                    return dom.param(dom.serializeArray(form));
                },
                serializeArray : function(form){
                    // 不直接转换form.elements,防止以下情况:   <form > <input name="elements"/><input name="test"/></form>
                    var elements = dom.slice(form||[]), ret = []
                    elements.forEach(function(elem){
                        if( elem.name && !elem.disabled && ( "checked" in elem ? elem.checked : 1 )){
                            var val = dom( elem ).val();
                            if(Array.isArray(val)){
                                val.forEach(function(value){
                                    ret.push({
                                        name: elem.name,
                                        value: value.replace( rCRLF, "\r\n" )
                                    });
                                });
                            }else if(typeof val == "string"){
                                ret.push({
                                    name: elem.name,
                                    value: val.replace( rCRLF, "\r\n" )
                                });
                            }
                        }
                    });
                    return ret;
                },
                param : function( object ) {//objectToQuery
                    var ret = [];
                    function add( key, value ){
                        ret[ ret.length ] = encode(key) + '=' + encode(value);
                    }
                    if ( Array.isArray(object) ) {
                        for ( var i = 0, length = object.length; i < length; i++ ) {
                            add( object[i].name, object[i].value );
                        }
                    } else {
                        function buildParams(obj, prefix) {
                            if ( Array.isArray(obj) ) {
                                for ( var i = 0, length = obj.length; i < length; i++ ) {
                                    buildParams( obj[i], prefix );
                                }
                            } else if( dom.isPlainObject(obj) ) {
                                for ( var j in obj ) {
                                    var postfix = ((j.indexOf("[]") > 0) ? "[]" : ""); // move the brackets to the end (if applicable)
                                    buildParams(obj[j], (prefix ? (prefix+"["+j.replace("[]", "")+"]"+postfix) : j) );
                                }
                            } else {
                                add( prefix, dom.isFunction(obj) ? obj() : obj );
                            }
                        }
                        buildParams(obj);
                    }
                    return ret.join("&").replace(r20, "+");
                }
            });
    
            var ajax = dom.ajax = function(object) {
                if (!object.url) {
                    return undefined;
                }
                var options = normalizeOptions(object),//规整化参数对象
                //创建一个伪XMLHttpRequest,能处理complete,success,error等多投事件
                dummyXHR = new dom.jXHR(options),
                dataType = options.dataType;
    
                if(options.form && options.form.nodeType ==1){
                    dataType = "iframe";
                }else if(dataType == "jsonp"){
                    if(options.crossDomain){
                        ajax.fire("start", dummyXHR, options.url,options.jsonp);//用于jsonp请求
                        dataType = "script"
                    }else{
                        dataType = dummyXHR.options.dataType = "json";
                    }
                }
                var transportContructor = transports[dataType] || transports._default,
                transport = new transportContructor();
                transport.dummyXHR = dummyXHR;
                dummyXHR.transport = transport;
                if (options.contentType) {
                    dummyXHR.setRequestHeader("Content-Type", options.contentType);
                }
    
                //添加dataType所需要的Accept首部
                dummyXHR.setRequestHeader( "Accept", accepts[dataType] ? accepts[ dataType ] +  ", */*; q=0.01"  : accepts[ "*" ] );
                for (var i in options.headers) {
                    dummyXHR.setRequestHeader(i, options.headers[ i ]);
                }
    
                "Complete Success Error".replace(dom.rword, function(name){
                    var method = name.toLowerCase();
                    dummyXHR[method] = dummyXHR["on"+name];
                    if(typeof options[method] === "function"){
                        dummyXHR[method](options[method]);
                        delete dummyXHR.options[method];
                        delete options[method];
                    }
                });
                dummyXHR.readyState = 1;
                // Timeout
                if (options.async && options.timeout > 0) {
                    dummyXHR.timeoutID = setTimeout(function() {
                        dummyXHR.abort("timeout");
                    }, options.timeout);
                }
    
                try {
                    dummyXHR.state = 1;//已发送
                    transport.send();
                } catch (e) {
                    if (dummyXHR.status < 2) {
                        dummyXHR.callback(-1, e);
                    } else {
                        dom.log(e);
                    }
                }
    
                return dummyXHR;
            }
    
            dom.mix(ajax, dom.emitter);
            ajax.isLocal = rlocalProtocol.test(ajaxLocParts[1]);
            /**
             * jXHR类,用于模拟原生XMLHttpRequest的所有行为
             */
            dom.jXHR = dom.factory({
                include:dom.emitter,
                init:function(option){
                    dom.mix(this, {
                        responseData:null,
                        timeoutID:null,
                        responseText:null,
                        responseXML:null,
                        responseHeadersString:"",
                        responseHeaders:null,
                        requestHeaders:{},
                        readyState:0,
                        //internal state
                        state:0,
                        statusText:null,
                        status:0,
                        transport:null
                    });
    
                    this.defineEvents("complete success error");
                    this.setOptions(option);
                },
    
                fire: function(type){
                    var target = this, table = dom.data( target,"@events") ,args = dom.slice(arguments,1);
                    if(!table) return;
                    var queue = table[type];
                    if (  queue ) {
                        for ( var i = 0, bag; bag = queue[i++]; ) {
                            bag.callback.apply( target, args );
                        }
                    }
                },
    
                setRequestHeader: function(name, value) {
                    this.requestHeaders[ name ] = value;
                    return this;
                },
    
                getAllResponseHeaders: function() {
                    return this.state === 2 ? this.responseHeadersString : null;
                },
                getResponseHeader: function(key,/*internal*/ match) {
                    if (this.state === 2) {
                        if (!this.responseHeaders) {
                            this.responseHeaders = {};
                            while (( match = rheaders.exec(this.responseHeadersString) )) {
                                this.responseHeaders[ match[1] ] = match[ 2 ];
                            }
                        }
                        match = this.responseHeaders[ key];
                    }
                    return match === undefined ? null : match;
                },
                // 重写 content-type 首部
                overrideMimeType: function(type) {
                    if (!this.state) {
                        this.mimeType = type;
                    }
                    return this;
                },
    
                // 中止请求
                abort: function(statusText) {
                    statusText = statusText || "abort";
                    if (this.transport) {
                        this.transport._callback(0, 1);
                    }
                    this.callback(0, statusText);
                    return this;
                },
                /**
                 * 用于触发success,error,complete等回调
                 * http://www.cnblogs.com/rubylouvre/archive/2011/05/18/2049989.html
                 * @param {Number} status 状态码
                 * @param {String} statusText 对应的扼要描述
                 */
                callback:function(status, statusText) {
                    // 只能执行一次,防止重复执行
                    // 例如完成后,调用 abort
                    // 到这要么成功,调用success, 要么失败,调用 error, 最终都会调用 complete
                    if (this.state == 2) {//2:已执行回调
                        return;
                    }
                    this.state = 2;
                    this.readyState = 4;
                    var isSuccess;
                    if (status >= 200 && status < 300 || status == 304) {
                        if (status == 304) {
                            statusText = "notmodified";
                            isSuccess = true;
                        } else {
                            var text = this.responseText, xml = this.responseXML,dataType = this.options.dataType;
                            try{
                                dom.log(text)
                                this.responseData = converters[dataType](this, text, xml);
                                statusText = "success";
                                isSuccess = true;
                                dom.log("dummyXHR.callback success");
                            } catch(e) {
                                dom.log("dummyXHR.callback parsererror")
                                statusText = "parsererror : " + e;
                            }
                        }
    
                    }
                    else {
                        if (status < 0) {
                            status = 0;
                        }
                    }
    
                    this.status = status;
                    this.statusText = statusText;
                    if (this.timeoutID) {
                        clearTimeout(this.timeoutID);
                    }
                    if (isSuccess) {
                        this.fire("success",this.responseData,statusText);
                    } else {
                        this.fire("error",this.responseData,statusText);
                    }
                    this.fire("complete",this.responseData,statusText);
                    this.transport = undefined;
                }
            });
    
            //http://www.cnblogs.com/rubylouvre/archive/2010/04/20/1716486.html
            //【XMLHttpRequest】传送器,专门用于上传
            var s = ["XMLHttpRequest",
            "ActiveXObject('Msxml2.XMLHTTP.6.0')",
            "ActiveXObject('Msxml2.XMLHTTP.3.0')",
            "ActiveXObject('Msxml2.XMLHTTP')",
            "ActiveXObject('Microsoft.XMLHTTP')"];
            if( !-[1,] && global.ScriptEngineMinorVersion() === 7 && location.protocol === "file:"){
                s.shift();
            }
            for(var i = 0 ,axo;axo = s[i++];){
                try{
                    if(eval("new "+ axo)){
                        dom.xhr = new Function( "return new "+axo);
                        break;
                    }
                }catch(e){}
            }
            if (dom.xhr) {
                var nativeXHR = new dom.xhr(), allowCrossDomain = false;
                if ("withCredentials" in nativeXHR) {
                    allowCrossDomain = true;
                }
                //添加通用XMLHttpRequest传送器
                transports._default =  dom.factory({
                    //发送请求
                    send:function() {
                        var self = this,
                        dummyXHR = self.dummyXHR,
                        options = dummyXHR.options;
                        dom.log("XhrTransport.sending.....");
                        if (options.crossDomain && !allowCrossDomain) {
                            dom.error("do not allow crossdomain xhr !");
                            return;
                        }
    
                        var nativeXHR = new dom.xhr(), i;
                        self.xhr = nativeXHR;
                        if (options.username) {
                            nativeXHR.open(options.type, options.url, options.async, options.username, options.password)
                        } else {
                            nativeXHR.open(options.type, options.url, options.async);
                        }
                        // Override mime type if supported
                        if (dummyXHR.mimeType && nativeXHR.overrideMimeType) {
                            nativeXHR.overrideMimeType(dummyXHR.mimeType);
                        }
                        // 用于进入request.xhr?分支
                        if (!options.crossDomain && !dummyXHR.requestHeaders["X-Requested-With"]) {
                            dummyXHR.requestHeaders[ "X-Requested-With" ] = "XMLHttpRequest";
                        }
                        try {
                            for (i in dummyXHR.requestHeaders) {
                                nativeXHR.setRequestHeader(i, dummyXHR.requestHeaders[ i ]);
                            }
                        } catch(e) {
                            dom.log(" nativeXHR setRequestHeader occur error ");
                        }
    
                        nativeXHR.send(options.hasContent && options.data || null);
                        //在同步模式中,IE6,7可能会直接从缓存中读取数据而不会发出请求,因此我们需要手动发出请求
                        if (!options.async || nativeXHR.readyState == 4) {
                            self._callback();
                        } else {
                            nativeXHR.onreadystatechange = function() {
                                self._callback();
                            }
                        }
                    },
    
                    //用于获取原始的responseXMLresponseText 修正status statusText
                    //第二个参数为1时中止清求
                    _callback:function(event, isAbort) {
                        // Firefox throws exceptions when accessing properties
                        // of an xhr when a network error occured
                        // http://helpful.knobs-dials.com/index.php/Component_returned_failure_code:_0x80040111_(NS_ERROR_NOT_AVAILABLE)
                        try {
                            var self = this,nativeXHR = self.xhr, dummyXHR = self.dummyXHR;
                            if (isAbort || nativeXHR.readyState == 4) {
                                nativeXHR.onreadystatechange = dom.noop;
                                if (isAbort) {
                                    // 完成以后 abort 不要调用
                                    if (nativeXHR.readyState !== 4) {
                                        //IE的XMLHttpRequest.abort实现于 MSXML 3.0+
                                        //http://blogs.msdn.com/b/xmlteam/archive/2006/10/23/using-the-right-version-of-msxml-in-internet-explorer.aspx
                                        try{
                                            nativeXHR.abort &&  nativeXHR.abort();
                                        }catch(e){};
                                    }
                                } else {
                                    var status = nativeXHR.status;
                                    dummyXHR.responseHeadersString = nativeXHR.getAllResponseHeaders();
                                    var xml = nativeXHR.responseXML;
                                    // Construct response list
                                    if (xml && xml.documentElement /* #4958 */) {
                                        dummyXHR.responseXML = xml;
                                    }
                                    dummyXHR.responseText = nativeXHR.responseText;
                                    //火狐在跨城请求时访问statusText值会抛出异常
                                    try {
                                        var statusText = nativeXHR.statusText;
                                    } catch(e) {
                                        statusText = "";
                                    }
                                    //用于处理特殊情况,如果是一个本地请求,只要我们能获取数据就假当它是成功的
                                    if (!status && ajax.isLocal && !dummyXHR.options.crossDomain) {
                                        status = dummyXHR.responseText ? 200 : 404;
                                    //IE有时会把204当作为1223
                                    //returning a 204 from a PUT request - IE seems to be handling the 204 from a DELETE request okay.
                                    } else if (status === 1223) {
                                        status = 204;
                                    }
                                    dummyXHR.callback(status, statusText);
                                }
                            }
                        } catch (firefoxAccessException) {
                            dom.log(firefoxAccessException)
                            nativeXHR.onreadystatechange = dom.noop;
                            if (!isAbort) {
                                dummyXHR.callback(-1, firefoxAccessException);
                            }
                        }
                    }
                });
    
            }
            //【script节点】传送器,只用于跨域的情况
            transports.script = dom.factory({
                send:function() {
                    var self = this,
                    dummyXHR = self.dummyXHR,
                    options = dummyXHR.options,
                    head = dom.HEAD,
                    script = self.script = DOC.createElement("script");
                    script.async = "async";
                    dom.log("ScriptTransport.sending.....");
                    if (options.charset) {
                        script.charset = options.charset
                    }
                    //当script的资源非JS文件时,发生的错误不可捕获
                    script.onerror = script.onload = script.onreadystatechange = function(e) {
                        e = e || global.event;
                        self._callback((e.type || "error").toLowerCase());
                    };
                    script.src = options.url
                    head.insertBefore(script, head.firstChild);
                },
    
                _callback:function(event, isAbort) {
                    var node = this.script,
                    dummyXHR = this.dummyXHR;
                    if (isAbort || dom.rreadystate.test(node.readyState)  || event == "error"  ) {
                        node.onerror = node.onload = node.onreadystatechange = null;
                        var parent = node.parentNode;
                        if(parent && parent.nodeType === 1){
                            parent.removeChild(node);
                            this.script = undefined;
                        }
                        //如果没有中止请求并没有报错
                        if (!isAbort && event != "error") {
                            dummyXHR.callback(200, "success");
                        }
                        // 非 ie<9 可以判断出来
                        else if (event == "error") {
                            dummyXHR.callback(500, "scripterror");
                        }
                    }
                }
            });
    
            //http://www.decimage.com/web/javascript-cross-domain-solution-with-jsonp.html
            //JSONP请求,借用【script节点】传送器
            converters["script json"] = function(dummyXHR){
                return dom["jsonp"+ dummyXHR.uniqueID ]();
            }
            ajax.bind("start", function(e, dummyXHR, url, jsonp) {
                dom.log("jsonp start...");
                var jsonpCallback = "jsonp"+dummyXHR.uniqueID;
                dummyXHR.options.url = url  + (rquery.test(url) ? "&" : "?" ) + jsonp + "=" + DOC.URL.replace(/(#.+|\W)/g,'')+"."+jsonpCallback;
                dummyXHR.options.dataType = "script json";
                //将后台返回的json保存在惰性函数中
                global.dom[jsonpCallback]= function(json) {
                    global.dom[jsonpCallback] = function(){
                        return json;
                    };
                };
            });
    
            function createIframe(dummyXHR, transport) {
                var id = "iframe-upload-"+dummyXHR.uniqueID;
                var iframe = dom.parseHTML("<iframe " +
                    " id='" + id + "'" +
                    " name='" + id + "'" +
                    " style='display:none'/>").firstChild;
                iframe.transport = transport;
                return   (DOC.body || DOC.documentElement).insertBefore(iframe,null);
            }
    
            function addDataToForm(data, form) {
                var input = DOC.createElement("input"), ret = [];
                input.type = 'hidden';
                dom.serializeArray(data).forEach(function(obj){
                    var elem =  input.cloneNode(true);
                    elem.name = obj.name;
                    elem.value = obj.value;
                    form.appendChild(elem);
                    ret.push(elem);
                });
                return ret;
            }
            //【iframe】传送器,专门用于上传
            //http://www.profilepicture.co.uk/tutorials/ajax-file-upload-xmlhttprequest-level-2/ 上传
            transports.iframe = dom.factory({
                send:function() {
                    var self = this,
                    dummyXHR = self.dummyXHR,
                    options = dummyXHR.options,
                    form = options.form
                    //form.enctype的值
                    //1:application/x-www-form-urlencoded	在发送前编码所有字符(默认)
                    //2:multipart/form-data	不对字符编码。在使用包含文件上传控件的表单时,必须使用该值。
                    //3:text/plain	空格转换为 "+" 加号,但不对特殊字符编码。
                    this.backups = {
                        target:form.target || "",
                        action:form.action || "",
                        enctype:form.enctype,
                        method:form.method
                    };
    
                    var iframe = createIframe(dummyXHR, this);
                    //必须指定method与enctype,要不在FF报错
                    //“表单包含了一个文件输入元素,但是其中缺少 method=POST 以及 enctype=multipart/form-data,所以文件将不会被发送。”
                    // 设置target到隐藏iframe,避免整页刷新
                    form.target =  "iframe-upload-"+dummyXHR.uniqueID;
                    form.action =  options.url;
                    form.method =  "POST";
                    form.enctype = "multipart/form-data";
                    this.fields = options.data ? addDataToForm(options.data, form) : [];
                    this.form = form;//一个表单元素
                    dom.log("iframe transport...");
                    dom(iframe).bind("load",this._callback).bind("error",this._callback);
                    form.submit();
                },
    
                _callback:function(event  ) {
                    var iframe = this,
                    transport =  iframe.transport;
                    // 防止重复调用 , 成功后 abort
                    if (!transport) {
                        return;
                    }
                    dom.log("transports.iframe _callback")
                    var form = transport.form,
                    eventType = event.type,
                    dummyXHR = transport.dummyXHR;
                    iframe.transport = undefined;
                    if (eventType == "load") {
                        var doc = iframe.contentDocument ? iframe.contentDocument : window.frames[iframe.id].document;
                        var iframeDoc = iframe.contentWindow.document;
                        if (doc.XMLDocument) {
                            dummyXHR.responseXML = doc.XMLDocument;
                        } else if (doc.body){
                            // response is html document or plain text
                            dummyXHR.responseText = doc.body.innerHTML;
                            dummyXHR.responseXML = iframeDoc;
                            //当,MIME为"text/plain",浏览器会把文本放到一个PRE标签中
                            if (doc.body.firstChild && doc.body.firstChild.nodeName.toUpperCase() == 'PRE') {
                                dummyXHR.responseText  = doc.body.firstChild.firstChild.nodeValue;
                            }
                        }else {
                            // response is a xml document
                            dummyXHR.responseXML = doc;
                        }
                        dummyXHR.callback(200, "success");
                    } else if (eventType == 'error') {
                        dummyXHR.callback(500, "error");
                    }
                    for(var i in transport.backups){
                        form[i] = transport.backups[i];
                    }
                    //还原form的属性
                    transport.fields.forEach(function(elem){
                        elem.parentNode.removeChild(elem);
                    });
                    dom(iframe).unbind("load",transport._callback).unbind("error",transport._callback);
                    iframe.clearAttributes &&  iframe.clearAttributes();
                    setTimeout(function() {
                        // Fix busy state in FF3
                        iframe.parentNode.removeChild(iframe);
                        dom.log("iframe.parentNode.removeChild(iframe)")
                    }, 0);
    
                }
            });
    
        });
    
    })(this,this.document);
    //2011.8.31
    //将会传送器的abort方法上传到dom.jXHR.abort去处理
    //修复serializeArray的bug
    //对XMLHttpRequest.abort进行try...catch
    

    JSONP请求示例

            dom.ajax({
              url:"http://del.icio.us/feeds/json/fans/stomita",
              type:"get",
              success:function(responseData){
                dom.log(responseData+"  success");
              },
              dataType:"jsonp"
            });
    
    

    api基本与jQuery兼容,如get,post,getScript,getJSON,ajax等等,还多出一个upload用于iframe上传。

    一个上传示例:

    
          dom.require("ready,ajax,event",function(){
            dom("#i33").click(function(e){
              dom.log("click")
              dom.upload("/home/upload",dom("#aaa")[0],function(text){
                alert(text)
              });
            })
          });
    

    对应的页面:

        <form id="aaa" >
          <input type="file" id="file" name="file" style="450"/>
          <input type="submit" value="上传文件" id="i33"/>
          <span id="msg"></span>
          <br/>
          <font color="red">支持JPG,JPEG,GIF,BMP,SWF,RMVB,RM,AVI文件的上传</font>
        </form>
    
  • 相关阅读:
    如何在Oracle中复制表结构和表数据
    linux --备份oracle
    Jira-Clone与发邮件的使用
    C# lock关键词/lock语句块、线程锁
    HTML5实现简单圆周运动示例
    C#使用FFmpeg 将视频格式转换成Gif图片示例
    C#使用FFmpeg 将视频格式转换成MP4示例
    ffmpeg ffplay ffprobe资料整理
    Asp.Net MVC是否针对每次请求都重新创建一个控制器实例
    Asp.Net MVC--Controller激活2
  • 原文地址:https://www.cnblogs.com/rubylouvre/p/2151479.html
Copyright © 2011-2022 走看看