再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调用代码如下
- 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)
- ??
- 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[this.url]; ??
- ????????if(!wsdl)? ??
- ????????{ ??
- ????????????var?op?=?{method:'GET',async:?false}; ??
- ????????????var?wsdlAjax?=?new?XHR(op).send(this.url?+?"?wsdl",?null);?????????? ??
- ????????????wsdl?=?wsdlAjax.transport.responseXML; ??
- ????????????WSDLS[this.url]?=?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)
?
- 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[this.url];??
- ????????if(!wsdl)???
- ????????{??
- ????????????var?op?=?{method:'GET',async:?false};??
- ????????????var?wsdlAjax?=?new?XHR(op).send(this.url?+?"?wsdl",?null);????????????
- ????????????wsdl?=?wsdlAjax.transport.responseXML;??
- ????????????WSDLS[this.url]?=?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[i],"name")?==?this.method)??
- ????????????{??
- ????????????????objNode?=?ell[i];??
- ????????????????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[i],"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[0].childNodes[0].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(":")[1];??
- ????????????ell?=?objNode.getElementsByTagName(tagName);???????????
- ????????}??
- ????????return?ell;??
- ????},??
- ????getElementAttrValue?:?function(objNode,attrName)??
- ????{??
- ????????var?rtnValue?=?"";??
- ??????????
- ????????if(objNode?==?null)?return?rtnValue;??
- ??????????
- ????????if(objNode.attributes[attrName]?+?""?==?"undefined")??
- ????????{???
- ????????????if(objNode.attributes.getNamedItem(attrName)?!=?null)??
- ????????????????rtnValue?=?objNode.attributes.getNamedItem(attrName).nodeValue?;??
- ??????????????
- ????????}??
- ????????else??
- ????????{??
- ????????????if(objNode.attributes[attrName]?!=?null)??
- ????????????????rtnValue?=?objNode.attributes[attrName].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[i].split(splitChar).length?==?1)?contrnue;??
- ??
- ????????????var?key?=?this[i].split(splitChar)[0].trim();??
- ????????????var?value?=?this[i].split(splitChar)[1].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;??
- }??
相应的调用代码如下:
?
?
- <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>??