    /*
     *  错误类型
     */
    _ERROR_TYPE_OPERATION_EXCEPTION = 0;
    _ERROR_TYPE_KNOWN_EXCEPTION = 1;
    _ERROR_TYPE_UNKNOWN_EXCEPTION = 2;
    /*
     *  通讯用XML节点名
     */
    _XML_NODE_RESPONSE_ROOT = "Response";
    _XML_NODE_RESPONSE_ERROR = "Error";
    _XML_NODE_RESPONSE_SUCCESS = "Success";
    _XML_NODE_REQUEST_ROOT = "Request";
    _XML_NODE_REQUEST_NAME = "Name";
    _XML_NODE_REQUEST_VALUE = "Value";
    _XML_NODE_REQUEST_PARAM = "Param";    
    /*
     *  XML节点类型
     */
    _XML_NODE_TYPE_ELEMENT = 1;
    _XML_NODE_TYPE_ATTRIBUTE = 2;
    _XML_NODE_TYPE_TEXT = 3;
    _XML_NODE_TYPE_CDATA = 4;
	_XML_NODE_TYPE_PROCESSING = 7;
	_XML_NODE_TYPE_COMMENT = 8;
    _XML_NODE_TYPE_DOCUMENT = 9;
    /*
     *  HTTP响应状态
     */
    _HTTP_RESPONSE_STATUS_LOCAL_OK = 0;
    _HTTP_RESPONSE_STATUS_REMOTE_OK = 200;
    /*
     *  HTTP响应解析结果类型
     */
    _HTTP_RESPONSE_DATA_TYPE_EXCEPTION = "exception";
    _HTTP_RESPONSE_DATA_TYPE_SUCCESS = "success";
    _HTTP_RESPONSE_DATA_TYPE_DATA = "data";
    /*
     *  HTTP超时
     */
    _HTTP_TIMEOUT = 10000;



    /*
     *  对象名称：XMLHTTP请求参数对象
     *  职责：负责配置XMLHTTP请求参数
     *
     */
    function HttpRequestParams(){
        this.url = "";
        this.method = "POST";											//默认请求方式POST
        this.async = true;												//默认异步
        this.content = {};												//存放提交数据各个字段
        this.header = {};												//存放http头信息
    }
    /*
     *	函数说明：设置发送数据
     *	参数：  string:name 		数据字段名
                string:value        数据内容
                boolean:flag        同名是否覆盖(默认true)
     *	返回值：
     *	作者：毛云
     *	日期：2006-4-25
     *
     */
    HttpRequestParams.prototype.setContent = function(name,value,flag){
        if(false!=flag){
            //默认覆盖
            this.content[name] = value;
        }else{
            //不覆盖，追加
            var oldValue = this.content[name];
            if(null==oldValue){
                //原先没有值
                this.content[name] = value;
            }else if(oldValue instanceof Array){
                //原先已经是数组
                oldValue[oldValue.length] = value;
                this.content[name] = oldValue;                
            }else{
                //原先是单值
                this.content[name] = [oldValue,value];
            }
        }
    }
    /*
     *	函数说明：设置xform专用格式发送数据
     *	参数：	XmlNode:dataNode 	XmlNode实例，xform的data数据节点
                string:prefix 	    提交字段前缀
     *	返回值：
     *	作者：毛云
     *	日期：2006-6-26
     *
     */
    HttpRequestParams.prototype.setXFormContent = function(dataNode,prefix){
        if("data"==dataNode.nodeName){
            var nodes = dataNode.selectNodes("./row/*");
            for(var i=0,iLen=nodes.length;i<iLen;i++){
                var name = nodes[i].nodeName;
                var value = nodes[i].text;

                //2006-7-19 从data节点上获取保存名，如果没有则用原名
                var rename = dataNode.getAttribute(name);
                if(null!=rename){
                    name = rename;
                }

                if(null!=prefix){
                    name = prefix + "." + name;
                }

                this.setContent(name,value,false);
            }
        }
    }
    /*
     *	函数说明：清除发送数据
     *	参数：	string:name 		数据字段名
     *	返回值：
     *	作者：毛云
     *	日期：2006-4-25
     *
     */
    HttpRequestParams.prototype.clearContent = function(name){
        delete this.content[name];
    }
    /*
     *	函数说明：清除所有发送数据
     *	参数：	
     *	返回值：
     *	作者：毛云
     *	日期：2006-4-25
     *
     */
    HttpRequestParams.prototype.clearAllContent = function(){
        this.content = {};
    }
    /*
     *	函数说明：设置请求头信息
     *	参数：	string:name 		头信息字段名
                string:value        头信息内容
     *	返回值：
     *	作者：毛云
     *	日期：2006-4-25
     *
     */
    HttpRequestParams.prototype.setHeader = function(name,value){
        this.header[name] = value;
    }





    /*
     *  对象名称：XMLHTTP请求对象
     *  职责：负责发起XMLHTTP请求并接收响应数据
     *
     */
    function HttpRequest(paramsInstance){
        this.value = "";

        this.xmlhttp = new XmlHttp();
        this.xmldom = new XmlReader();

        this.params = paramsInstance;
    }    
    /*
     *	函数说明：获取响应数据源代码
     *	参数：	
     *	返回值：string:result       响应数据源代码
     *	作者：毛云
     *	日期：2006-4-25
     *
     */
    HttpRequest.prototype.getResponseText = function(){
        var result = this.value;
        return result;
    }
    /*
     *	函数说明：获取响应数据XML文档对象
     *	参数：	
     *	返回值：XmlReader:xmlReader       XML文档对象
     *	作者：毛云
     *	日期：2006-4-25
     *
     */
    HttpRequest.prototype.getResponseXml = function(){
        var xmlReader = this.xmldom;
        return xmlReader;
    }
    /*
     *	函数说明：获取响应数据XML文档指定节点对象值
     *	参数：	string:name             指定节点名
     *	返回值：any:value               根据节点内容类型不同而定
     *	作者：毛云
     *	日期：2006-4-25
     *
     */
    HttpRequest.prototype.getNodeValue = function(name){
        var value = null;

        if(null!=this.xmldom.documentElement){
            var documentElement = new XmlNode(this.xmldom.documentElement);
            var node = documentElement.selectSingleNode("/" + _XML_NODE_RESPONSE_ROOT + "/" + name);

            if(null!=node){
                var data = null;
                var datas = node.selectNodes("node()");
                for(var i=0,iLen=datas.length;i<iLen;i++){
                    var tempData = datas[i];
                    switch(tempData.nodeType){
                        case _XML_NODE_TYPE_TEXT:
                            if(""!=tempData.nodeValue.replace(/\s*/g,"")){
                                data = tempData;
                            }
                            break;
                        case _XML_NODE_TYPE_ELEMENT:
                        case _XML_NODE_TYPE_CDATA:
                            data = tempData;
                            break;
                    }
                    if(null!=data){
                        break;
                    }
                }

                if(null!=data){
                    //2006-7-1 返回复制节点，以便清除整个原始文档
                    data = data.cloneNode(true);

                    switch(data.nodeType){
                        case _XML_NODE_TYPE_ELEMENT:
                            value = data;
                            break;
                        case _XML_NODE_TYPE_TEXT:
                        case _XML_NODE_TYPE_CDATA:
                            value = data.nodeValue;
                            break;
                    }
                }
            }
        }
        return value;
    }
    /*
     *	函数说明：发起XMLHTTP请求
     *	参数：boolean:wait      是否等待其余请求完成再发送
     *	返回值：
     *	作者：毛云
     *	日期：2006-4-25
     *
     */
    HttpRequest.prototype.send = function(wait){
        var oThis = this;

        //等待其余请求完成再发送
        if(true==wait){
            var count = HttpRequests.getCount();
            if(0==count){
                oThis.send();
            }else{
                HttpRequests.onFinishAll(function(){
                    oThis.send();
                });
            }
            return;
        }


        try{
            if(false != this.params.ani){
                Public.showWaitingLayer();
            }

            this.xmlhttp.onreadystatechange = function() {
                if(4==oThis.xmlhttp.readyState){
                    oThis.clearTimeout();

                    var response = {};
                    response.responseText = oThis.xmlhttp.responseText;
                    response.responseXML = oThis.xmlhttp.responseXML;
                    response.status = oThis.xmlhttp.status;
                    response.statusText = oThis.xmlhttp.statusText;

                    if(true != oThis.isAbort){
                        setTimeout(function(){
                            oThis.abort();

                            Public.hideWaitingLayer();
                            oThis.onload(response);

                            //从队列中去除
                            HttpRequests.del(oThis);
                            oThis.execCallback();
                        },100);
                    }else{
                        Public.hideWaitingLayer();

                        //从队列中去除
                        HttpRequests.del(oThis);
                        oThis.execCallback();                    
                    }
                }
            }
            this.xmlhttp.open(this.params.method, this.params.url, this.params.async);

            //2007-5-15 增加超时判定
            this.setTimeout();

            this.packageContent();
            this.setCustomRequestHeader();
            this.xmlhttp.send(this.requestBody);

            //存入队列
            HttpRequests.add(this);


        }catch(e){
            Public.hideWaitingLayer();

            //throw e;
            var tempParserResult = {};
            tempParserResult.dataType = _HTTP_RESPONSE_DATA_TYPE_EXCEPTION;
            tempParserResult.type = 1;
            tempParserResult.msg = e.description;
            tempParserResult.description = e.description;
            tempParserResult.source = "";

            this.onexception(tempParserResult);
        }
    }
    /*
     *	函数说明：超时中断请求
     *	参数：	
     *	返回值：   
     *	作者：毛云
     *	日期：2007-5-15
     *
     */
    HttpRequest.prototype.setTimeout = function(noConfirm){
        var oThis = this;
        this.timeout = setTimeout(function(){
            if(true!=noConfirm && true==confirm("服务器响应较慢，需要中断请求吗？")){
                oThis.isAbort = true;
                oThis.abort();
                oThis.isAbort = false;
            }else{
                oThis.clearTimeout();
                oThis.setTimeout(true);
            }
        },_HTTP_TIMEOUT);
    }
    /*
     *	函数说明：清除超时
     *	参数：	
     *	返回值：   
     *	作者：毛云
     *	日期：2007-5-15
     *
     */
    HttpRequest.prototype.clearTimeout = function(){
        clearTimeout(this.timeout);
    }
    /*
     *	函数说明：对发送数据进行封装
     *	参数：	
     *	返回值：    XmlReader:contentXml    XmlReader实例
     *	作者：毛云
     *	日期：2006-4-25
     *
     */
    HttpRequest.prototype.packageContent = function(){
        var contentStr = "";
        var contentXml = new XmlReader("<"+_XML_NODE_REQUEST_ROOT+"/>");
        var contentXmlRoot = new XmlNode(contentXml.documentElement);

        function setParamNode(name,value){
            var tempNameNode = contentXml.createElement(_XML_NODE_REQUEST_NAME);
            var tempCDATANode = contentXml.createCDATA(name);
            tempNameNode.appendChild(tempCDATANode);

            var tempValueNode = contentXml.createElement(_XML_NODE_REQUEST_VALUE);
            var tempCDATANode = contentXml.createCDATA(value);
            tempValueNode.appendChild(tempCDATANode);

            var tempParamNode = contentXml.createElement(_XML_NODE_REQUEST_PARAM);
            tempParamNode.appendChild(tempNameNode);
            tempParamNode.appendChild(tempValueNode);

            contentXmlRoot.appendChild(tempParamNode);
        
        }

        for(var name in this.params.content){
            var value = this.params.content[name];
            if(value==null){
                continue;
            }

            if(value instanceof Array){
                for(var i=0,iLen=value.length;i<iLen;i++){
                    setParamNode(name,value[i]);                
                }
            }else{
                setParamNode(name,value);
            }
        }
        contentStr = contentXml.toXml();
        this.xmlhttp.setRequestHeader("Content-Length",contentStr.length);
        this.requestBody = contentStr;
    }
    /*
     *	函数说明：设置自定义请求头信息
     *	参数：	
     *	返回值：
     *	作者：毛云
     *	日期：2006-4-25
     *
     */
    HttpRequest.prototype.setCustomRequestHeader = function(){
        this.xmlhttp.setRequestHeader("REQUEST-TYPE","xmlhttp");
        this.xmlhttp.setRequestHeader("REFERER", this.params.url);
        for(var item in this.params.header){											//设置自定义http头信息
            var itemValue = String(this.params.header[item]);
            if(itemValue!=""){
                this.xmlhttp.setRequestHeader(item, itemValue);
            }
        }
        this.xmlhttp.setRequestHeader("CONTENT-TYPE","text/xml");
        this.xmlhttp.setRequestHeader("CONTENT-TYPE","application/octet-stream");
    }
    /*
     *	函数说明：加载数据完成，对结果进行处理
     *	参数：	Object:response     该对象各属性值继承自xmlhttp对象
     *	返回值：
     *	作者：毛云
     *	日期：2006-4-25
     *
     */
    HttpRequest.prototype.onload = function(response){
        this.value = response.responseText;

        //远程200本地0才允许
        var httpStatus = response.status;
        var httpStatusText = response.statusText;
        if(httpStatus!=_HTTP_RESPONSE_STATUS_LOCAL_OK && httpStatus!=_HTTP_RESPONSE_STATUS_REMOTE_OK){
            var param = {};
            param.dataType = _HTTP_RESPONSE_DATA_TYPE_EXCEPTION;
            param.type = 1;
            param.source = this.value;
            param.msg = "HTTP " + httpStatus + " 错误\r\n" + httpStatusText;
            param.description = "请求远程地址\"" + this.params.url + "\"出错";
            new Message_Exception(param,this);
            this.returnValue = false;
            return;
        }

        var responseParser = new HTTP_Response_Parser(this.value);

        //将通过解析后的xmlReader赋予xmldom
        this.xmldom = responseParser.xmlReader;

        if(responseParser.result.dataType==_HTTP_RESPONSE_DATA_TYPE_EXCEPTION){
            new Message_Exception(responseParser.result,this);
            this.returnValue = false;
        }else if(responseParser.result.dataType==_HTTP_RESPONSE_DATA_TYPE_SUCCESS){
            new Message_Success(responseParser.result,this);
            this.returnValue = true;
        }else{
            this.ondata();
            this.onresult();
            this.returnValue = true;

            //2006-7-2 当返回数据中含脚本内容则自动执行
            var script = this.getNodeValue("script");
            if(null!=script){
                //创建script元素并添加到head中
                var headObj = document.getElementsByTagName("head")[0];
                if(null!=headObj){
                    var scriptObj = document.createElement("script");
                    scriptObj.text = script;
                    headObj.appendChild(scriptObj);
                }
            }
        }

        //2006-7-1 清除原始文档
        this.xmldom.loadXML("");
    }
    HttpRequest.prototype.ondata = HttpRequest.prototype.onresult = HttpRequest.prototype.onsuccess = HttpRequest.prototype.onexception = function(){
    
    }
    /*
     *	函数说明：终止XMLHTTP请求
     *	参数：	
     *	返回值：
     *	作者：毛云
     *	日期：2007-3-14
     *
     */
    HttpRequest.prototype.abort = function(){
        if(null!=this.xmlhttp){
            this.xmlhttp.abort();
        }
    }
    /*
     *	函数说明：执行回调函数
     *	参数：	
     *	返回值：
     *	作者：毛云
     *	日期：2007-5-29
     *
     */
    HttpRequest.prototype.execCallback = function(){
      if(0 == HttpRequests.getCount()){
        if(null != HttpRequests.callback){
          HttpRequests.callback();
          HttpRequests.callback = null;
        }
      }
    }



    /*
     *  对象名称：HTTP_Response_Parser对象
     *  职责：负责分析处理后台响应数据
     *
     *  成功信息格式
     *  <Response>
     *      <Success>
     *          <type>1</type>
     *          <msg><![CDATA[ ]]></msg>
     *          <description><![CDATA[ ]]></description>
     *      </Success>
     *  </Response>
     *
     *  错误信息格式
     *  <Response>
     *      <Error>
     *          <type>1</type>
     *          <relogin>1</relogin>
     *          <msg><![CDATA[ ]]></msg>
     *          <description><![CDATA[ ]]></description>
     *      </Error>
     *  </Response>
     */
    function HTTP_Response_Parser(responseText){
        this.source = responseText;
        this.xmlReader = new XmlReader(responseText);
        this.init();	
    }
    /*
     *	函数说明：初始化实例
     *	参数：	
     *	返回值：
     *	作者：毛云
     *	日期：2006-4-25
     *
     */
    HTTP_Response_Parser.prototype.init = function(){
        this.result = {};
        var parseError = this.xmlReader.getParseError();
        if(null!=parseError){
            this.result.dataType = _HTTP_RESPONSE_DATA_TYPE_EXCEPTION;
            this.result.source = this.source;
            this.result.msg = "服务器异常";
            this.result.description = "数据出错在第" + parseError.line + "行第" + parseError.linepos + "字符\r\n" + parseError.reason;
        }else{
            var documentNode = new XmlNode(this.xmlReader.documentElement);
            var firstChildNode = documentNode.selectSingleNode("/"+_XML_NODE_RESPONSE_ROOT+"/*");

            if(null==firstChildNode){		//未找到有效节点则认为是异常信息
                this.result.dataType = _HTTP_RESPONSE_DATA_TYPE_EXCEPTION;
            }else if(firstChildNode.nodeName==_XML_NODE_RESPONSE_ERROR){		//只要有Error节点就认为是异常信息
                this.result.dataType = _HTTP_RESPONSE_DATA_TYPE_EXCEPTION;
                this.result.source = this.source;

                var detailNodes = firstChildNode.selectNodes("*");
                for(var i=0;i<detailNodes.length;i++){
                    var tempName = detailNodes[i].nodeName;
                    var tempValue = detailNodes[i].text;
                    this.result[tempName] = tempValue;
                }
            }else if(firstChildNode.nodeName==_XML_NODE_RESPONSE_SUCCESS){	//只要有Success就认为是成功信息
                this.result.dataType = _HTTP_RESPONSE_DATA_TYPE_SUCCESS;

                var detailNodes = firstChildNode.selectNodes("*");
                for(var i=0;i<detailNodes.length;i++){
                    var tempName = detailNodes[i].nodeName;
                    var tempValue = detailNodes[i].text;
                    this.result[tempName] = tempValue;
                }
            }else{
                this.result.dataType = _HTTP_RESPONSE_DATA_TYPE_DATA;
            }
        }
    }


    /*
     *  对象名称：XmlHttp对象
     *  职责：负责XmlHttp对象创建
     *
     */
    function XmlHttp(){
        if(window.ActiveXObject){
            return new ActiveXObject("MSXML2.XMLHTTP");
        }else if(window.XMLHttpRequest){
            return new XMLHttpRequest();
        }else{
            alert("您的浏览器不支持XMLHTTP");
            return null;
        }
    }


    /*
     *  对象名称：Message_Exception对象
     *  职责：负责处理异常信息
     *
     */
    function Message_Exception(param,request){
        request.ondata();

        var str = [];
        str[str.length] = "Error";
        str[str.length] = "type=\"" + param.type + "\"";
        str[str.length] = "msg=\"" + param.msg + "\"";
        str[str.length] = "description=\"" + param.description + "\"";
        str[str.length] = "source=\"" + param.source + "\"";

        if("0"!=param.type && "0" != request.params.type){
            alert(param.msg,str.join("\r\n"));
        }

        request.onexception(param);

        //初始化默认值
        if(null!=request.params.relogin){
            param.relogin = request.params.relogin;
        }else if(null==param.relogin){//默认不重新登录
            param.relogin = "0";
        }
        if(param.relogin=="1"){
            //先清除令牌
            Cookie.del("token","/" + CONTEXTPATH);

            var loginObj = window.showModalDialog(URL_CORE + "_relogin.htm",{title:"请重新登录"},"dialogWidth:250px;dialogHeight:200px;resizable:yes");
            if(null!=loginObj){
                var p = request.params;
                p.setHeader("loginName",loginObj.loginName);
                p.setHeader("password",loginObj.password);
                p.setHeader("identifier",loginObj.identifier);

                request.send();
            }
        }else if(param.relogin=="2"){
            //先清除令牌
            Cookie.del("token","/" + CONTEXTPATH);

            var loginObj = window.showModalDialog(URL_CORE + "_relogin2.htm",{title:"请重新输入密码"},"dialogWidth:250px;dialogHeight:200px;resizable:yes");
            if(null!=loginObj){
                p.setHeader("pwd",loginObj.password);

                request.send();
            }
        }
    }
    /*
     *  对象名称：Message_Success对象
     *  职责：负责处理成功信息
     *
     */
    function Message_Success(param,request){
        request.ondata();

        var str = [];
        str[str.length] = "Success";
        str[str.length] = "type=\"" + param.type + "\"";
        str[str.length] = "msg=\"" + param.msg + "\"";
        str[str.length] = "description=\"" + param.description + "\"";

        if("0"!=param.type && "0" != request.params.type){
            alert(param.msg,str.join("\r\n"));
        }

        request.onsuccess(param);
    }




    /*
     *	对象名称：HttpRequests（全局静态对象）
     *	职责：负责所有http请求连接
     *
     */
    var HttpRequests = {};
    HttpRequests.items = [];
    /*
     *	函数说明：终止所有请求连接
     *	参数：	
     *	返回值：
     *	作者：毛云
     *	日期：2007-3-14
     *
     */
    HttpRequests.closeAll = function(){
        for(var i=0,iLen=this.items.length;i<iLen;i++){
            this.items[i] = true;
            this.items[i].abort();
            this.items[i] = false;
        }
    }
    /*
     *	函数说明：加入一个请求连接
     *	参数：	
     *	返回值：
     *	作者：毛云
     *	日期：2007-3-14
     *
     */
    HttpRequests.add = function(request){
        this.items[this.items.length] = request;
    }
    /*
     *	函数说明：去除一个请求连接
     *	参数：	
     *	返回值：
     *	作者：毛云
     *	日期：2007-3-14
     *
     */
    HttpRequests.del = function(request){
        for(var i=0,iLen=this.items.length;i<iLen;i++){
            if(this.items[i]==request){
                this.items.splice(i,1);
                break;
            }
        }
    }
    /*
     *	函数说明：统计当前连接数
     *	参数：	
     *	返回值：
     *	作者：毛云
     *	日期：2007-5-29
     *
     */
    HttpRequests.getCount = function(){
        return this.items.length;
    }
    /*
     *	函数说明：等待当前请求全部结束
     *	参数：	
     *	返回值：
     *	作者：毛云
     *	日期：2007-5-29
     *
     */
    HttpRequests.onFinishAll = function(callback){
      this.callback = callback;
    }