haiyang08101 发表于 2013-1-29 11:38:32

使用javascript调用webservice示例

再javascript中使用soap调用webservice的示例代码

代码再IE6和FF测试通过,对于c#写的webservice和java(xfire)写的,都测试过,没有问题

此代码原型来源于 http://www.guru4.net/ 的javascript soapclient

发现这个下载的js只能用于调用c#的webservice,所以利用mootools,重新封装,达到IE和火狐的兼容的同时,兼容java和c#

(再例子中使用的 mootools.v1.11.js 文件,做过修改)

客户端js调用代码如下

js 代码
----------------------------------------------------------------------
function ajaxRequest()   
    {   
      var url = "http://localhost:88/webservicedemo.asmx";   
            
      //设置webService传入参数   
      //   
      //注意:   
      //   
      //    调用.Net 写的webservice(如例子中的webservicedemo.asmx)   
      //         HelloTo(String name)   针对name参数必须写成 <name></name>wqj,还有更多参数一样写,使用名称匹配   
      //         传入的参数数量可以不等于(多于或少于)方法要求的参数   
      //   
      //    调用java(xfire) 发布的webService   
      //         传入的参数必须与调用方法的参数数量相等,且按传入值的顺序进行匹配   
      //   
            
      var para = "<name></name>wqj"; 这里应该是一个标准的xml形式,源码贴出来时被虑掉了,请参看附件源码   
            
      var op = {   
                  data:para,   
                  onComplete: showResponse,   
                  onFailure:showError,   
                  update:'ajaxBack'   
               };   
   
      var service = new WebService(url,"HelloTo",op);   
      service.request();   
      return false;   
    }   
    function showError(obj)   
    {   
      //obj 是一个xmlHttpRequest对象   
      alert("error");   
    }   
    function showResponse(requestText,requestXML)   
    {   
      //requestText 返回的文本   
      //requestXML 返回的XML   
      alert("ok");   
    }   

WebService类的代码如下(webservice.js)

js 代码

   
var WSDLS = {};   
   
var WebService = new Class({   
   
    url : '',   
    method : '',   
    options:   
    {   
      method:'GET',   
      data: null,   
      update: null,   
      onComplete: Class.empty,   
      onError:Class.empty,   
      evalScripts: false,   
      evalResponse: false   
    },   
      
    initialize: function(url,method,options)   
    {   
      this.url = url;   
      this.method = method;   
      this.options = options;   
   
    },   
      
    request : function()   
    {   
      var wsdl = WSDLS;   
      if(!wsdl)   
      {   
            var op = {method:'GET',async: false};   
            var wsdlAjax = new XHR(op).send(this.url + "?wsdl", null);            
            wsdl = wsdlAjax.transport.responseXML;   
            WSDLS = wsdl;   
      }   
      this.setSoap(wsdl);   
    },   
            
    setSoap : function(wsdl)   
    {   
            
      var ns = (wsdl.documentElement.attributes["targetNamespace"] + "" == "undefined") ? wsdl.documentElement.attributes.getNamedItem("targetNamespace").nodeValue : wsdl.documentElement.attributes["targetNamespace"].value;   
      var sr =   
                "" +   
                ""
                "xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" " +   
                "xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" " +   
                "xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">" +   
                "<soap:body>"</soap:body> +   
                "<" + this.method + " xmlns=\"" + ns + "\">" +   
                     (this.options.data === null ?"":this.options.data) +   
                " + this.method + ">;   
            
      this.options.method = 'post';   
      this.options.data = null;   
            
      var soapaction = ((ns.lastIndexOf("/") != ns.length - 1) ? ns + "/" : ns) + this.method;   
            
      var soapAjax = new Ajax(this.url,this.options);   
      soapAjax.setHeader("SOAPAction", soapaction);   
      soapAjax.setHeader("Content-type", "text/xml; charset=utf-8");   
      soapAjax.request(sr);   
    }   
      
});   

在第一个版本中存在以下问题

1. 不能根据webservice的要求输入参数自动组织参数

2. 没有处理返回值

3.一旦webservice调用过程出错,会形成一个死循环(一直弹出error)




V2 说明


1. 解决第一版中死循环的问题

2. 统一输入参数的传入形式(与mootools的ajax使用方式完全一致),形式如name=wqj&age=20&........

3. 自动根据参数名对应的值,组织webservice的传入参数,只根据webservice要求的参数名查找对应的值

    与顺序不再有关系.(对于xfire中的输入参数使用名称 in0,in1........)

    传入的参数数量也不再要求一致,多的自动丢弃,少的自动传空


4. 对于返回的XML,增加提取方法,返回需要的关键返回值(去掉XML的框框)

详细参照附件源码,下面是部分关键代码




WebService类的代码如下(webservice.js)


js 代码
var WSDLS = {};   
   
var WebService = new Class({   
   
    url : '',   
    method : '',   
    options:   
    {   
      method:'GET',   
      data: null,   
      update: null,   
      onComplete: Class.empty,   
      onError:Class.empty,   
      evalScripts: false,   
      evalResponse: false   
    },   
      
    initialize: function(url,method,options)   
    {         
      this.url = url;   
      this.method = method;   
      this.options = options;   
    },   
      
    request : function()   
    {   
      var wsdl = WSDLS;   
      if(!wsdl)   
      {   
            var op = {method:'GET',async: false};   
            var wsdlAjax = new XHR(op).send(this.url + "?wsdl", null);            
            wsdl = wsdlAjax.transport.responseXML;   
            WSDLS = wsdl;   
      }   
   
      this.setSoap(wsdl);   
    },   
         
    setSoap : function(wsdl)   
    {   
      var paraXML = this.getParaXML(wsdl);   
      alert(paraXML);   
      var ns = (wsdl.documentElement.attributes["targetNamespace"] + "" == "undefined") ? wsdl.documentElement.attributes.getNamedItem("targetNamespace").nodeValue : wsdl.documentElement.attributes["targetNamespace"].value;   
      var sr =   
                "" +   
                " +   
                "xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" " +   
                "xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" " +   
                "xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">" +   
                "<soap:body>"</soap:body> +   
                "<" + this.method + " xmlns=\"" + ns + "\">" +   
                  paraXML+   
                " + this.method + ">";   
         
      this.options.method = 'post';   
      this.options.data = null;   
         
      var soapaction = ((ns.lastIndexOf("/") != ns.length - 1) ? ns + "/" : ns) + this.method;   
   
      var soapAjax = new Ajax(this.url,this.options);   
      soapAjax.setHeader("SOAPAction", soapaction);   
      soapAjax.setHeader("Content-type", "text/xml; charset=utf-8");   
      soapAjax.request(sr);   
    },   
    getParaXML : function(wsdl)   
    {   
         
      var objNode = null;   
      var rtnValue = "";   
      //java(xfire)   
      var ell = this.getElementsByTagName(wsdl,"xsd:element");      
      if(ell.length == 0)   
      {   
            //c#   
            ell = this.getElementsByTagName(wsdl,"s:element");   
      }   
      for(var i = 0; i < ell.length; i++)   
      {   
            if(this.getElementAttrValue(ell,"name") == this.method)   
            {   
                objNode = ell;   
                break;   
            }   
      }   
   
      if(objNode == null) return rtnValue;   
      //java(xfire)   
      ell = this.getElementsByTagName(objNode,"xsd:element");   
      if(ell.length == 0)   
      {   
            //c#   
            ell = this.getElementsByTagName(objNode,"s:element");   
      }   
      if(ell.length == 0) return rtnValue ;   
         
      var hash = new Hash();   
         
      if(this.options.data != null && this.options.data.clean != "")   
      {   
            hash = this.options.data.split("&").toHash("=");   
      }   
         
      for(var i = 0; i < ell.length; i++)   
      {   
            var paraName = this.getElementAttrValue(ell,"name");   
            rtnValue = rtnValue + this.getSingleXML(paraName,hash);   
      }   
         
      return rtnValue;   
    },   
      
    getSingleXML : function (name,hash)   
    {   
      name = name.trim();   
         
      var rtnValue = "";   
      if(hash.hasKey(name))   
      {   
            rtnValue = hash.get(name);   
      }   
      rtnValue = "<" + name + ">" + xmlscc(rtnValue) + " + name + ">"   
      return rtnValue;   
    },   
    getBackData: function(xml)   
    {   
      var rtnValue = "";   
      //java(xfire)   
      var soap = this.getElementsByTagName(xml,"ns1:out");      
      if(soap.length == 0)   
      {   
            //c#   
            soap = this.getElementsByTagName(xml,this.method + "Result");   
      }   
      return soap.childNodes.nodeValue;      
         
    },   
    getElementsByTagName : function(objNode,tagName)   
    {   
      //tagName 形式如 xsd:element ,写出tag的全称   
   
      var ell;   
      if(this.isIE())   
      {   
            ell = objNode.getElementsByTagName(tagName);      
      }   
      else   
      {   
            if(tagName.contains(":")) tagName = tagName.split(":");   
            ell = objNode.getElementsByTagName(tagName);            
      }   
      return ell;   
    },   
    getElementAttrValue : function(objNode,attrName)   
    {   
      var rtnValue = "";   
         
      if(objNode == null) return rtnValue;   
         
      if(objNode.attributes + "" == "undefined")   
      {   
            if(objNode.attributes.getNamedItem(attrName) != null)   
                rtnValue = objNode.attributes.getNamedItem(attrName).nodeValue ;   
               
      }   
      else   
      {   
            if(objNode.attributes != null)   
                rtnValue = objNode.attributes.value;   
      }   
      return rtnValue;   
    },   
    isIE : function()   
    {   
      var isMSIE = /*@cc_on!@*/false;   
      return isMSIE;   
    }   
});   
   
Array.extend({   
      
    toHash : function (splitChar)   
    {   
      var hash = new Hash({});   
      for(var i=0;i<this.length;i++)   
      {   
               
            if(this.split(splitChar).length == 1) contrnue;   
   
            var key = this.split(splitChar).trim();   
            var value = this.split(splitChar).trim();   
               
            hash.set(key, value);   
      }   
         
      return hash;   
    }   
});   
   
function xmlscc(strData)   
{   
   
    strData=strData.replace(/&/g, "&");   
    strData=strData.replace(/>/g, ">");   
    strData=strData.replace(/"<");   
    strData=strData.replace(/"/g, """);
    strData=strData.replace(/'/g, "'");   
    return strData;   
}   
相应的调用代码如下:



js 代码

<script type=< span="">"text/javascript">   
      
    var service ;   
    function ajaxRequest()   
    {   
      var url = "http://localhost:88/webservicedemo.asmx";   
         
      //设置webService传入参数   
      //   
      //注意:   
      //   
      //    调用webservice(如例子中的webservicedemo.asmx)   
      //         HelloTo(String name)   针对name参数必须写成name=wqj ,还有更多参数一样写,使用&符号分隔(name=11&age=20&.....),使用名称匹配   
      //         传入的参数数量可以不等于(多于或少于)方法要求的参数   
         
         
      var para = "name=wqj";   
         
      var op = {   
                  data:para,   
                  onComplete: showResponse,   
                  onFailure:showError,   
                  update:'ajaxBack'   
               };   
   
      service = new WebService(url,"HelloTo",op);   
      service.request();   
      return false;   
    }   
    function showError(obj)   
    {   
      //obj 是一个xmlHttpRequest对象   
      alert("error");   
    }   
    function showResponse(requestText,requestXML)   
    {   
      //requestText 返回的文本   
      //requestXML 返回的XML   
      // service.getBackData 就是取出返回的XML中,实际需要的数据   
      //经过测试兼容 IE,FF   
      alert(service.getBackData(requestXML));   
         
    }   
    </script>   




----------------------------------------------------------------------



JavaScriptSOAP.rar (47.1 KB)
描述: js调用webservice示例

JavaScriptSOAP(V2).rar (49.5 KB)
描述: js,sope第二版
页: [1]
查看完整版本: 使用javascript调用webservice示例