再javascript中使用soap调用webservice的示例代码
代码再IE6和FF测试通过,对于c#写的webservice和java(xfire)写的,都测试过,没有问题
此代码原型来源于 [url]http://www.guru4.net/[/url] 的javascript soapclient
发现这个下载的js只能用于调用c#的webservice,所以利用mootools,重新封装,达到IE和火狐的兼容的同时,兼容java和c#
(再例子中使用的 mootools.v1.11.js 文件,做过修改)
客户端js调用代码如下
js 代码
1.function ajaxRequest()
2. {
3. var url = "http://localhost:88/webservicedemo.asmx";
4.
5. //设置webService传入参数
6. //
7. //注意:
8. //
9. // 调用.Net 写的webservice(如例子中的webservicedemo.asmx)
10. // HelloTo(String name) 针对name参数必须写成 <name></name>wqj,还有更多参数一样写,使用名称匹配
11. // 传入的参数数量可以不等于(多于或少于)方法要求的参数
12. //
13. // 调用java(xfire) 发布的webService
14. // 传入的参数必须与调用方法的参数数量相等,且按传入值的顺序进行匹配
15. //
16.
17. var para = "<name></name>wqj"; 这里应该是一个标准的xml形式,源码贴出来时被虑掉了,请参看附件源码
18.
19. var op = {
20. data:para,
21. onComplete: showResponse,
22. onFailure:showError,
23. update:'ajaxBack'
24. };
25.
26. var service = new WebService(url,"HelloTo",op);
27. service.request();
28. return false;
29. }
30. function showError(obj)
31. {
32. //obj 是一个xmlHttpRequest对象
33. alert("error");
34. }
35. function showResponse(requestText,requestXML)
36. {
37. //requestText 返回的文本
38. //requestXML 返回的XML
39. alert("ok");
40. }
WebService类的代码如下(webservice.js)
js 代码
1.
2.var WSDLS = {};
1.
2.var WebService = new Class({
1.
2. url : '',
3. method : '',
4. options:
5. {
6. method:'GET',
7. data: null,
8. update: null,
9. onComplete: Class.empty,
10. onError:Class.empty,
11. evalScripts: false,
12. evalResponse: false
13. },
14.
15. initialize: function(url,method,options)
16. {
17. this.url = url;
18. this.method = method;
19. this.options = options;
20.
21. },
22.
23. request : function()
24. {
25. var wsdl = WSDLS[this.url];
26. if(!wsdl)
27. {
28. var op = {method:'GET',async: false};
29. var wsdlAjax = new XHR(op).send(this.url + "?wsdl", null);
30. wsdl = wsdlAjax.transport.responseXML;
31. WSDLS[this.url] = wsdl;
32. }
33. this.setSoap(wsdl);
34. },
35.
36. setSoap : function(wsdl)
37. {
38.
39. var ns = (wsdl.documentElement.attributes["targetNamespace"] + "" == "undefined") ? wsdl.documentElement.attributes.getNamedItem("targetNamespace").nodeValue : wsdl.documentElement.attributes["targetNamespace"].value;
40. var sr =
41. "" +
42. ""
43. "xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" " +
44. "xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" " +
45. "xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">" +
46. "<soap:body>"</soap:body> +
47. "<" + this.method + " xmlns=\"" + ns + "\">" +
48. (this.options.data === null ?"":this.options.data) +
49. " + this.method + ">;
50.
51. this.options.method = 'post';
52. this.options.data = null;
53.
54. var soapaction = ((ns.lastIndexOf("/") != ns.length - 1) ? ns + "/" : ns) + this.method;
55.
56. var soapAjax = new Ajax(this.url,this.options);
57. soapAjax.setHeader("SOAPAction", soapaction);
58. soapAjax.setHeader("Content-type", "text/xml; charset=utf-8");
59. soapAjax.request(sr);
60. }
61.
62.});
在第一个版本中存在以下问题
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 代码
1.var WSDLS = {};
2.
3.var WebService = new Class({
4.
5. url : '',
6. method : '',
7. options:
8. {
9. method:'GET',
10. data: null,
11. update: null,
12. onComplete: Class.empty,
13. onError:Class.empty,
14. evalScripts: false,
15. evalResponse: false
16. },
17.
18. initialize: function(url,method,options)
19. {
20. this.url = url;
21. this.method = method;
22. this.options = options;
23. },
24.
25. request : function()
26. {
27. var wsdl = WSDLS[this.url];
28. if(!wsdl)
29. {
30. var op = {method:'GET',async: false};
31. var wsdlAjax = new XHR(op).send(this.url + "?wsdl", null);
32. wsdl = wsdlAjax.transport.responseXML;
33. WSDLS[this.url] = wsdl;
34. }
35.
36. this.setSoap(wsdl);
37. },
38.
39. setSoap : function(wsdl)
40. {
41. var paraXML = this.getParaXML(wsdl);
42. alert(paraXML);
43. var ns = (wsdl.documentElement.attributes["targetNamespace"] + "" == "undefined") ? wsdl.documentElement.attributes.getNamedItem("targetNamespace").nodeValue : wsdl.documentElement.attributes["targetNamespace"].value;
44. var sr =
45. "" +
46. " +
47. "xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" " +
48. "xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" " +
49. "xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">" +
50. "<soap:body>"</soap:body> +
51. "<" + this.method + " xmlns=\"" + ns + "\">" +
52. paraXML +
53. " + this.method + ">";
54.
55. this.options.method = 'post';
56. this.options.data = null;
57.
58. var soapaction = ((ns.lastIndexOf("/") != ns.length - 1) ? ns + "/" : ns) + this.method;
59.
60. var soapAjax = new Ajax(this.url,this.options);
61. soapAjax.setHeader("SOAPAction", soapaction);
62. soapAjax.setHeader("Content-type", "text/xml; charset=utf-8");
63. soapAjax.request(sr);
64. },
65. getParaXML : function(wsdl)
66. {
67.
68. var objNode = null;
69. var rtnValue = "";
70. //java(xfire)
71. var ell = this.getElementsByTagName(wsdl,"xsd:element");
72. if(ell.length == 0)
73. {
74. //c#
75. ell = this.getElementsByTagName(wsdl,"s:element");
76. }
77. for(var i = 0; i < ell.length; i++)
78. {
79. if(this.getElementAttrValue(ell[i],"name") == this.method)
80. {
81. objNode = ell[i];
82. break;
83. }
84. }
85.
86. if(objNode == null) return rtnValue;
87. //java(xfire)
88. ell = this.getElementsByTagName(objNode,"xsd:element");
89. if(ell.length == 0)
90. {
91. //c#
92. ell = this.getElementsByTagName(objNode,"s:element");
93. }
94. if(ell.length == 0) return rtnValue ;
95.
96. var hash = new Hash();
97.
98. if(this.options.data != null && this.options.data.clean != "")
99. {
100. hash = this.options.data.split("&").toHash("=");
101. }
102.
103. for(var i = 0; i < ell.length; i++)
104. {
105. var paraName = this.getElementAttrValue(ell[i],"name");
106. rtnValue = rtnValue + this.getSingleXML(paraName,hash);
107. }
108.
109. return rtnValue;
110. },
111.
112. getSingleXML : function (name,hash)
113. {
114. name = name.trim();
115.
116. var rtnValue = "";
117. if(hash.hasKey(name))
118. {
119. rtnValue = hash.get(name);
120. }
121. rtnValue = "<" + name + ">" + xmlscc(rtnValue) + " + name + ">"
122. return rtnValue;
123. },
124. getBackData: function(xml)
125. {
126. var rtnValue = "";
127. //java(xfire)
128. var soap = this.getElementsByTagName(xml,"ns1:out");
129. if(soap.length == 0)
130. {
131. //c#
132. soap = this.getElementsByTagName(xml,this.method + "Result");
133. }
134. return soap[0].childNodes[0].nodeValue;
135.
136. },
137. getElementsByTagName : function(objNode,tagName)
138. {
139. //tagName 形式如 xsd:element ,写出tag的全称
140.
141. var ell;
142. if(this.isIE())
143. {
144. ell = objNode.getElementsByTagName(tagName);
145. }
146. else
147. {
148. if(tagName.contains(":")) tagName = tagName.split(":")[1];
149. ell = objNode.getElementsByTagName(tagName);
150. }
151. return ell;
152. },
153. getElementAttrValue : function(objNode,attrName)
154. {
155. var rtnValue = "";
156.
157. if(objNode == null) return rtnValue;
158.
159. if(objNode.attributes[attrName] + "" == "undefined")
160. {
161. if(objNode.attributes.getNamedItem(attrName) != null)
162. rtnValue = objNode.attributes.getNamedItem(attrName).nodeValue ;
163.
164. }
165. else
166. {
167. if(objNode.attributes[attrName] != null)
168. rtnValue = objNode.attributes[attrName].value;
169. }
170. return rtnValue;
171. },
172. isIE : function()
173. {
174. var isMSIE = /*@cc_on!@*/false;
175. return isMSIE;
176. }
177.});
178.
179.Array.extend({
180.
181. toHash : function (splitChar)
182. {
183. var hash = new Hash({});
184. for(var i=0;i<this.length;i++)
185. {
186.
187. if(this[i].split(splitChar).length == 1) contrnue;
188.
189. var key = this[i].split(splitChar)[0].trim();
190. var value = this[i].split(splitChar)[1].trim();
191.
192. hash.set(key, value);
193. }
194.
195. return hash;
196. }
197.});
198.
199.function xmlscc(strData)
200.{
201.
202. strData=strData.replace(/&/g, "&");
203. strData=strData.replace(/>/g, ">");
204. strData=strData.replace(/"<");
205. strData=strData.replace(/"/g, """);
206. strData=strData.replace(/'/g, "'");
207. return strData;
208.}
相应的调用代码如下:
js 代码
1.<script type=< span="">"text/javascript">
2.
3. var service ;
4. function ajaxRequest()
5. {
6. var url = "http://localhost:88/webservicedemo.asmx";
7.
8. //设置webService传入参数
9. //
10. //注意:
11. //
12. // 调用webservice(如例子中的webservicedemo.asmx)
13. // HelloTo(String name) 针对name参数必须写成name=wqj ,还有更多参数一样写,使用&符号分隔(name=11&age=20&.....),使用名称匹配
14. // 传入的参数数量可以不等于(多于或少于)方法要求的参数
15.
16.
17. var para = "name=wqj";
18.
19. var op = {
20. data:para,
21. onComplete: showResponse,
22. onFailure:showError,
23. update:'ajaxBack'
24. };
25.
26. service = new WebService(url,"HelloTo",op);
27. service.request();
28. return false;
29. }
30. function showError(obj)
31. {
32. //obj 是一个xmlHttpRequest对象
33. alert("error");
34. }
35. function showResponse(requestText,requestXML)
36. {
37. //requestText 返回的文本
38. //requestXML 返回的XML
39. // service.getBackData 就是取出返回的XML中,实际需要的数据
40. //经过测试兼容 IE,FF
41. alert(service.getBackData(requestXML));
42.
43. }
44. </script>