再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";
-
-
-
-
-
-
-
-
-
-
-
-
-
- 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)
- {
-
- alert("error");
- }
- function showResponse(requestText,requestXML)
- {
-
-
- 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[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)
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 = "";
-
- var ell = this.getElementsByTagName(wsdl,"xsd:element");
- if(ell.length == 0)
- {
-
- 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;
-
- ell = this.getElementsByTagName(objNode,"xsd:element");
- if(ell.length == 0)
- {
-
- 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 = "";
-
- var soap = this.getElementsByTagName(xml,"ns1:out");
- if(soap.length == 0)
- {
-
- soap = this.getElementsByTagName(xml,this.method + "Result");
- }
- return soap[0].childNodes[0].nodeValue;
-
- },
- getElementsByTagName : function(objNode,tagName)
- {
-
-
- 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 = 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;
- }
相应的调用代码如下:
js 代码
- <script type=< span="">"text/javascript">
-
- var service ;
- function ajaxRequest()
- {
- var url = "http://localhost:88/webservicedemo.asmx";
-
-
-
-
-
-
-
-
-
-
- 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)
- {
-
- alert("error");
- }
- function showResponse(requestText,requestXML)
- {
-
-
-
-
- alert(service.getBackData(requestXML));
-
- }
- </script>