仿jquery.js的ajax写的msxmlhttp:serverXmlHttp.js,专用于win拉取数据用

邹正阳
2023-12-01

加强一个出错提示

_______________________________code________________________

('undefined' == typeof _) && (_ = {});
if (!_.msajax) {
    _.msajax = function(url, options){
    /*
     * 返回值:ms的xmlhttp对象,可以使用 返回对象.abort();终止运行
     * url:提交地址
     * options: 可用的属性,见下面的变量defaultOps 的说明,及使用示例
     *              
     */        
        if (('string' != typeof url) || !url.length) return alert('使用_.msajax第一个参数为有效url');
        if ('object' != typeof options) options = {};
                
        var obj2vars = function (obj) {
            if (null == obj) return '';
            if ('string' == typeof obj) return obj;
            
            if ('object' == typeof obj) {
                var r = [];
                
                for (var s in obj) {
                    r[r.length] = s + '=' + encodeURIComponent(obj[s]);//使用utf-8编码,如果是php可能是自动解码
                }
                
                return r.join('&');
            }
            
            return '';
        };
        var setNun = function(newInt, defInt) {
            newInt *= 1;
            return newInt > 0 ? newInt : defInt;
        }
        var setStr = function(newStr, def) {
            return ('string' == typeof newStr) && !/^\s*$/.test(newStr) ? newStr : def;
        }
        var setYes = function (nv, def) {
            return 'undefined' == typeof nv ? def : nv;
        }
        var callFunc = function (func, _this, def /*, ...*/) {
            if ( ('function' != typeof func) && ('function' != typeof def) ) return;
            var vars = [];
            
            for (var i = 3; i < arguments.length; i++) {
                vars[vars.length] = arguments[i];
            }
            
            _this = _this ? _this : arguments.callee;
            func = func ? func : def;
            
            try {
                func.apply(_this, vars);
            } catch (e) {
                alert('运行下面代码出错:' + e.description + '\n( \n' + func + '\n).apply(_this,' + vars + ') ');
            }
        }
        
        var defaultOps = {
            data:obj2vars(options.data) // 提交数据,{}或"var=val&var2=val2"串,注意提交数据默认使用utf-8编码
            ,resolves:setNun(options.resolves, 5000) // 数字,单位是ms,解析url成ip最长允许时间
            ,connects:setNun(options.connects, 60000) // 数字,单位是ms,连接到ip最长允许时间
            ,sends:setNun(options.sends, 30000) // 数字,单位是ms,发送data到ip最长允许时间
            ,receives:setNun(options.receives, 30000) // 数字,单位是ms,接收data最长允许时间
            ,start:options.start //function(){ /* 本次开始ajax前处理 */}
            ,stop:options.stop //function(){ /* 本次结束ajax后处理 */ }
            ,send:options.send //function(){ /* 发送数据时处理 */}
            ,complete:options.complete //function(){ /* 完成数据接收时处理 */ }
            ,type:setStr(options.type, 'POST') //注意必须是有效提交方式,默认是post提交
            ,contentType:setStr(options.contentType, 'application/x-www-form-urlencoded') //发送内容格式
            ,dataType:setStr(options.dataType, 'html') //表示接收时的格式,可用'html','json':会尝试解析js,出错时将导致success不触发,而触发error,'xml','text','binary', 'array',默认是'html'
            ,success:options.success //function(data){ /* 接收数据成功后处理方法 */ }
            ,error:options.error //function(data){ /* 出错处理方法 */ }
            ,beforeSend:options.beforeSend //function(xmlhttp){ /*发送前处理,比如加head,使用this来获取对象*/ }
            ,cache:options.cache //0或1,默认是0,是否缓存结果
            ,async:setYes(options.async, 1) //是否异步执行,注意这里必须使用false来设置,不能使用0
            ,headers:options.headers //{'发送头名称':'发送头值'}
            ,getAllHeaders:options.getAllHeaders //function(headers){ /* 发送成功后接收头部处理方法 */}
            ,getHeader:options.getHeader //指定获取某个head值,用法如后: {key:'某个header的key名称', func:function(val){ /* header的key值处理方法 */}}
            ,global: setYes(options.global, 1) //true|false(不能用0),false那么不会触发_.msajax.global.stop/start,注意这里前不会影响本次start,如果你也设置了它,只是是否要忽略全局的
            ,statusCode:options.statusCode //{'*':function(statusCode, statusText){ /*没指明的其它代码时通用处理方法*/} /*, 404:function(){404处理代码} */} //对应代码触发对应的动作,*表示默认处理方法
            ,proxy:options.proxy //是否使用路由,如果需要请按以下格式提供 {set:"0|1|2", path:"协议://ip地址:端口", user:'如果proxy需要验证', pwd:'如果需要密码'}
            ,user:options.user //请求是否需要提供http用户名
            ,pwd:options.pwd //请求是否需要提供http的密码
            //,charset:'UTF-8' //发送数据的编码,未实现
         };
        
        if (!defaultOps.cache) {
            url += (url.indexOf('?') > -1 ? '' : '?') + '&' + new Date().getTime();
        }
        
        var getReponse = function () {
            switch (defaultOps.dataType.toLowerCase()) {
                case 'html':
                case 'text':
                    return http.responseText;
                    break;
                case 'json':
                    window.onerror = function (){var e;for(var a in arguments) e += a + ' \t ' + arguments[a] + '\n\t';callFunc(defaultOps.error, 0, 0, '尝试把返回数据进行json解析时出错:' + e);};
                    try {
                        var json = http.responseText;
                        eval('json = ' + json + ';');
                        window.onerror = null;
                        return json;
                    } catch(e) {
                        callFunc(defaultOps.error, 0, 0, '尝试把返回数据进行json解析时出错:' + (e.description || e));
                    }
                    window.onerror = null;
                    break;
                case 'binary':
                    return http.responseStream;
                    break;
                case 'array':
                    return http.responseBody;
                    break;
                case 'xml':
                    return http.responseXML;
                    break;
                    
            }
        };
        var xml = "MSXML2.ServerXMLHTTP.6.0";
        var http = new ActiveXObject(xml);
        
        if (!http) {
            callFunc(defaultOps.complete);
            callFunc(defaultOps.stop);//本次的
            callFunc(_.msajax.global.stop);//全局的,末尾活跃对象时触发
            return alert(xml + "控件加载失败,可能是你的系统没有安装,请在网上搜索安装的方法或联系qq:80250771.");
        }
        
        http.setTimeouts(defaultOps.resolves, defaultOps.connects,  defaultOps.sends, defaultOps.receives);
        http.onreadystatechange = function(){
        /*
        (0) UNINITIALIZED   The object has been created but has not been initialized because the open method has not been called.

        (1) LOADING The object has been created but the send method has not been called.

        (2) LOADED  The send method has been called and the status and headers are available, but the response is not yet available.

        (3) INTERACTIVE Some data has been received. You can call responseBody and responseText to get the current partial results.

        (4) COMPLETED   All the data has been received, and the complete data is available in responseBody and responseText.
        */
            switch(http.readyState) {
                case 2:          
                    try {                      
                        callFunc(defaultOps.getAllHeaders, http, 0, http.getAllResponseHeaders());
                    } catch (e) {
                        callFunc(defaultOps.error, http, 0, '获取全部head值出错:' + (e.description || e));
                    }
                    try {
                        defaultOps.getHeader && defaultOps.getHeader.func(http.getResponseHeader(defaultOps.getHeader.key));
                    } catch (e) {
                        callFunc(defaultOps.error, http, 0, '获取head值' + defaultOps.getHeader.key + '出错:' + (e.description || e));
                    }
                    break;
                case 4:
                    switch (http.status){
                        /*
                        Number  Description
                        100  Continue
                        101  Switching protocols
                        200  OK
                        201  Created
                        202  Accepted
                        203  Non-Authoritative Information
                        204  No Content
                        205  Reset Content
                        206  Partial Content
                        300  Multiple Choices
                        301  Moved Permanently
                        302  Found
                        303  See Other
                        304  Not Modified
                        305  Use Proxy
                        307  Temporary Redirect
                        400  Bad Request
                        401  Unauthorized
                        402  Payment Required
                        403  Forbidden
                        404  Not Found
                        405  Method Not Allowed
                        406  Not Acceptable
                        407  Proxy Authentication Required
                        408  Request Timeout
                        409  Conflict
                        410  Gone
                        411  Length Required
                        412  Precondition Failed
                        413  Request Entity Too Large
                        414  Request-URI Too Long
                        415  Unsupported Media Type
                        416  Requested Range Not Suitable
                        417  Expectation Failed
                        500  Internal Server Error
                        501  Not Implemented
                        502  Bad Gateway
                        503  Service Unavailable
                        504  Gateway Timeout
                        505  HTTP Version Not Supported
                    */
                      case 200:
                            callFunc(defaultOps.success, 0, 0, getReponse());
                            break;
                        default:
                            if (defaultOps.statusCode) {
                                callFunc(defaultOps.statusCode[http.status], http, defaultOps.statusCode['*'], http.status, http.statusText);
                            } else {
                                callFunc(defaultOps.error, http, 0, '响应异常,代码:' + http.status + ';状态说明:' + http.statusText + ';body:' + getReponse());
                            }
                }
            
                callFunc(defaultOps.complete);
                callFunc(defaultOps.stop);//本次的
                callFunc(_.msajax.global.stop);//全局的,末尾活跃对象时触发
                break;
            }
        };      
        http.open(defaultOps.type.toUpperCase(), url, defaultOps.async, defaultOps.user, defaultOps.pwd);
        //setOption(option, value) //方法用法未明确
        
        if (defaultOps.proxy) {//此用法还需要研究一下
            http.setProxy(defaultOps.proxy.set, defaultOps.proxy.path);
            defaultOps.proxy.user && http.setProxyCredentials(defaultOps.proxy.user, defaultOps.proxy.pwd);
        }
    
        callFunc(defaultOps.start);//本次的
        callFunc(_.msajax.global.start);//全局的,首个活跃对象时触发
        try {
            http.setRequestHeader('Content-Type', defaultOps.contentType);
        } catch (e) {
            callFunc(defaultOps.error, http, 0, '设置发送head的数据格式时出错:' + (e.description || e));
        }
        callFunc(defaultOps.beforeSend, http);
        try {
            http.send(defaultOps.data);
        } catch (e) {
            callFunc(defaultOps.error, http, 0, '发送数据出错:' + (e.description || e));
        }
        callFunc(defaultOps.send);
        return http;
    };
    _.msajax.global = {stop:null /*  全局的 stop function 可以设置 */, start:null /* 全局的start function,可以设置 */};
};

________________________code_________________

 类似资料: