|
Hi vinh
There is a abort method on the XMLHttpRequest object, you can use this in combination with a setTimeout() call.
Have fun,
Marco
|
|
|
|
|
Where can we get the latest demo page that uses the advanced features(i.e. Passing complex parameters)
Thanks
|
|
|
|
|
|
Excellence works for this component. Some problem using with Java web services is that it return single value response as an object instead of value.
I did modify this message.
var nd = SOAPClient._getElementsByTagName(req.responseXML, method + "Response");
Anyway I can get the value by doing custom XML parser for any return type.
More question how to detect if server is down or no response?
|
|
|
|
|
I am unable to get your demo running yet.
* Where do i deploy the .asmx file? (I assume this is the server code? it isn't mentioned in the article)
* Any browser recommendations?
Thanks
Mike
|
|
|
|
|
|
Thanks.
Do I need to have .NET installed to run your demo?
I have had no success on Linux or Win2k.
Mike
|
|
|
|
|
Yes, the server-side code (web service) requires .net framework and a webserver such as IIS or Cassini (not on Linux, try on Windows 2000 or XP)
|
|
|
|
|
hi Boss
Tell me one thing what i should know for learning this.
All JavaScript stuffs are very far from me.Is it a special JS programming?
[M.Sendilkumar][Thomson][India]
|
|
|
|
|
What's about "special JS programming"?
This is a simple javascript functions library. See demos[^] for an usage example.
Enjoy!
Matteo Casati
|
|
|
|
|
Hello Sendilkumar.M,
You should look at or in this book:
http://www.amazon.com/gp/product/0072253576/sr=8-1/qid=1155057640/ref=sr_1_1/102-5264293-4452164?ie=UTF8
Everything you need to know about javascript is there.
Have fun,
Marco.
|
|
|
|
|
I'm having problems getting soapclient.js to work with my SOAP server. The problem is that the generated XML doesn't create a namespace for the calling method. By making the following change, I was able to get things to work. Is this a valid bug in soapclient.js?
**********************ORIGINAL CODE (line 123)**************
var failssr =
"<?xml version=\"1.0\" encoding=\"utf-8\"?>" +
"<soapenv:Envelope " +
"xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" " +
"xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" " +
"xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\">" +
"<soapenv:Body>" +
"<" + method + " xmlns=\"" + ns + "\">" +
parameters.toXml() +
"</" + method + "></soapenv:Body></soapenv:Envelope>";
***************MODIFIED CODE************************ <code>
var sr =
"<?xml version=\"1.0\" encoding=\"utf-8\"?>" +
"<soapenv:Envelope " +
"xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" " +
"xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" " +
"xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" " +
"xmlns:ns1=\"" + ns + "\">" +
"<soapenv:Body>" +
"<ns1:" + method + ">" +
parameters.toXml() +
"</ns1:" + method + "></soapenv:Body></soapenv:Envelope>";
</code>
-- modified at 13:41 Friday 7th July, 2006<code></code><code></code>
|
|
|
|
|
I had a similar issue. The problem wasn't that the method didn't have a namespace, it's that the children underneath the method (the parameters) ALSO used the same namespace, which messed things up.
My fix to that line of code was:
var sr =
"<?xml version=\"1.0\" encoding=\"utf-8\"?>" +
"<soapenv:Envelope " +
"xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" " +
"xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" " +
"xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\">" +
"<soapenv:Body>" +
"<ns1:" + method + " xmlns:ns1=\"" + ns + "\">" +
parameters.toXml() +
"</ns1:" + method + "></soap:Body></soap:Envelope>";
This makes it so the parameters don't use that namespace (ns1).
Daniel Tingstrom
|
|
|
|
|
I´ve changed some methods to make this more like a stub: it add´s the WSDL functions to the SOAPClient class. This means that we don´t have to get the correct url, methodname and type. I´ve used your code as a bases and made some new methods. It´s tested with your WSDL, Axis 1 WSDL and a gSOAP WSDL and they parsed.
Sorry VB.Net it took a little while to response, as you can see i´ve been busy.
The functions are added in a the following fashion: ws<WebserviceName><WebserviceMethod>(async, callback or null, params)
The constructor has been given to params: to parse or not to parse and the WSDL url.
Note: the stub only works on the global level, this means: NOT in a function. But i will look into this.
NEW code, I should have made clear that ie wasn´t working,
This is a test sample use Matteo's webservice:
<script>
var soapi = new SOAPClient("http://www.guru4.net/articoli/javascript-soap-client/demo/webservicedemo.asmx?wsdl", true);
function test() {
SOAPClient.wsWebServiceDemoSoapHelloTo(true, called, "Marco");
}
function called(back) {
alert(back);
}
</script>
<BUTTON onclick="test()" >TEST</BUTTON>
Have fun,
Marco.
/*****************************************************************************\
Javascript "SOAP Client" library
@version: 2.0 BETA 1 - 2006.03.12
@author: Matteo Casati - http://www.guru4.net/
@description: added support for complex object as webservice input paramaters
@version: 1.5 - 2006.02.20
@author: Matteo Casati, Martin Reich - http://www.guru4.net/
@description: the SOAPClient._onSendSoapRequest method has been updated
to handling SOAP exceptions in async calls
@version: 1.4 - 2005.12.10
@author: Matteo Casati, Ihar Voitka - http://www.guru4.net/
@description: (1) SOAPClientParameters.add() method returns 'this' pointer.
(2) "_getElementsByTagName" method added for xpath queries.
(3) "_getXmlHttpPrefix" refactored to "_getXmlHttpProgID" (full
ActiveX ProgID).
@version: 1.3 - 2005.12.06
@author: Matteo Casati - http://www.guru4.net/
@description: callback function now receives (as second - optional - parameter)
the SOAP response too. Thanks to Ihar Voitka.
@version: 1.2 - 2005.12.02
@author: Matteo Casati - http://www.guru4.net/
@description: (1) fixed update in v. 1.1 for no string params.
(2) the "_loadWsdl" method has been updated to fix a bug when
the wsdl is cached and the call is sync. Thanks to Linh Hoang.
@version: 1.1 - 2005.11.11
@author: Matteo Casati - http://www.guru4.net/
@description: the SOAPClientParameters.toXML method has been updated to allow
special characters ("<", ">" and "&"). Thanks to Linh Hoang.
@version: 1.0 - 2005.09.08
@author: Matteo Casati - http://www.guru4.net/
@notes: first release.
\*****************************************************************************/
//private
var _wsdl_url = null;
function SOAPClientParameters()
{
var _pl = new Array();
this.add = function(name, value)
{
_pl[name] = value;
return this;
}
this.toXml = function()
{
var xml = "";
for(var p in _pl)
xml += "<" + p + ">" + SOAPClientParameters._serialize(_pl[p]) + "</" + p + ">";
return xml;
}
}
SOAPClientParameters._serialize = function(o)
{
var s = "";
switch(typeof(o))
{
case "string":
s += o.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">"); break;
case "number":
case "boolean":
s += o.toString(); break;
case "object":
// Date
if(o.constructor.toString().indexOf("function Date()") > -1)
{
var year = o.getFullYear().toString();
var month = (o.getMonth() + 1).toString(); month = (month.length == 1) ? "0" + month : month;
var date = o.getDate().toString(); date = (date.length == 1) ? "0" + date : date;
var hours = o.getHours().toString(); hours = (hours.length == 1) ? "0" + hours : hours;
var minutes = o.getMinutes().toString(); minutes = (minutes.length == 1) ? "0" + minutes : minutes;
var seconds = o.getSeconds().toString(); seconds = (seconds.length == 1) ? "0" + seconds : seconds;
var milliseconds = o.getMilliseconds().toString();
var tzminutes = Math.abs(o.getTimezoneOffset());
var tzhours = 0;
while(tzminutes >= 60)
{
tzhours++;
tzminutes -= 60;
}
tzminutes = (tzminutes.toString().length == 1) ? "0" + tzminutes.toString() : tzminutes.toString();
tzhours = (tzhours.toString().length == 1) ? "0" + tzhours.toString() : tzhours.toString();
var timezone = ((o.getTimezoneOffset() < 0) ? "+" : "-") + tzhours + ":" + tzminutes;
s += year + "-" + month + "-" + date + "T" + hours + ":" + minutes + ":" + seconds + "." + milliseconds + timezone;
}
// Array
else if(o.constructor.toString().indexOf("function Array()") > -1)
{
for(var p in o)
{
if(!isNaN(p)) // linear array
{
(/function\s+(\w*)\s*\(/ig).exec(o[p].constructor.toString());
var type = RegExp.$1;
switch(type)
{
case "":
type = typeof(o[p]);
case "String":
type = "string"; break;
case "Number":
type = "int"; break;
case "Boolean":
type = "bool"; break;
case "Date":
type = "DateTime"; break;
}
s += "<" + type + ">" + SOAPClientParameters._serialize(o[p]) + "</" + type + ">"
}
else // associative array
s += "<" + p + ">" + SOAPClientParameters._serialize(o[p]) + "</" + p + ">"
}
}
// Object or custom function
else
for(var p in o)
s += "<" + p + ">" + SOAPClientParameters._serialize(o[p]) + "</" + p + ">";
break;
default:
throw new Error(500, "SOAPClientParameters: type '" + typeof(o) + "' is not supported");
}
return s;
}
/*
class to store method information
*/
function SOAPClientMethod(aName, aUrl, ns) {
this.name = aName;
this.url = aUrl;
this.namespace = ns;
this.paramsIn = {};
this.paramsOut = {};
this.method = "";
}
var global = this;
var soapClientMethods = {};
function SOAPClient(wsdl_url, createMethods)
{
_wsdl_url = wsdl_url;
this.methods = {};
if (_wsdl_url)
{
var xmlHttp = SOAPClient._getXmlHttp();
xmlHttp.open("GET", _wsdl_url, true);
xmlHttp.onreadystatechange = function()
{
if(xmlHttp.readyState == 4)
{
var uddi = xmlHttp.responseXML;
if (uddi)
{
var name = null;
var definition = SOAPClient._getElementsByTagName(uddi, "definitions")[0];
var namespace = definition.getAttribute("targetNamespace");
var services = SOAPClient._getElementsByTagName(uddi, "service");
for (var service = 0; service < services.length; service++)
{
var ports = SOAPClient._getElementsByTagName(services[service], "port");
for (var port = 0; port < ports.length; port++)
{
name = ports[port].getAttribute("name");
var addresses = SOAPClient._getElementsByTagName(ports[port], "address");
var bName = ports[port].getAttribute("binding").split(':')[1];
var bindings = SOAPClient._getElementsByTagName(uddi, "binding");
for (var binding = 0; binding < bindings.length; binding++)
{
if (bName == bindings[binding].getAttribute("name"))
{
var ptName = bindings[binding].getAttribute("type").split(':')[1];
var url = null;
for(var address = 0; address < addresses.length; address++)
{
url = addresses[address].getAttribute("location");
if (url != null) SOAPClient_cacheWsdl[url] = uddi;
}
var portTypes = SOAPClient._getElementsByTagName(uddi, "portType");
for(var portType = 0; portType < portTypes.length; portType++)
{
var prName = portTypes[portType].getAttribute("name");
if(prName == ptName)
{
var operations = SOAPClient._getElementsByTagName(portTypes[portType], "operation");
var messages = SOAPClient._getElementsByTagName(uddi, "message");
var elements = SOAPClient._getElementsByTagName(uddi, "element");
var complexTypes = SOAPClient._getElementsByTagName(uddi, "complexType");
var types = SOAPClient._getElementsByTagName(uddi, "types")[0];
for (var operation = 0;operation < operations.length; operation++)
{
var methodname = operations[operation].getAttribute("name");
soapClientMethods["ws" + name + methodname] = new SOAPClientMethod("ws" + name + methodname, url, namespace);
soapClientMethods["ws" + name + methodname].method = methodname;
var inputs = SOAPClient._getElementsByTagName( operations[operation], "input");
SOAPClient._processInputs(inputs, messages, types, complexTypes, soapClientMethods["ws" + name + methodname].paramsIn);
var outputs = SOAPClient._getElementsByTagName(operations[operation], "output");
SOAPClient._processInputs(outputs, messages, types, complexTypes, soapClientMethods["ws" + name + methodname].paramsOut);
}
}
}
}
}
}
}
}
var tmp;
for (s in soapClientMethods)
{
var pList = "(async, callback, ";
var params = "var soapP = new SOAPClientParameters();";
for (p in soapClientMethods[s].paramsIn)
{
pList += p + ", ";
params += "soapP.add(\"" + p + "\", " + p + ");";
}
pList = pList.substring(0, pList.lastIndexOf(","));
pList += ")";
//url, method, parameters, async, callback, soapClientMethod
var scriptText = "global._" + s + " = function " + pList + " {" + params
+ " return SOAPClient._sendSoapRequest2(\"" + soapClientMethods[s].url + "\", \""
+ soapClientMethods[s].method+"\", soapP, async, callback, soapClientMethods[\"" + s +
"\"]);}";
(global.eval) ? global.eval(scriptText) : eval(scriptText);
(global.eval) ? global.eval(("SOAPClient." + s + " = _" + s)) : eval(("SOAPClient." + s + " = _" + s));
if (eval("typeof(\"SOAPClient.\" + s)")=="string")
{
scriptText = "function _"+ s + pList + " {" + params
+ " return SOAPClient._sendSoapRequest2(\"" + soapClientMethods[s].url + "\", \""
+ soapClientMethods[s].method+"\", soapP, async, callback, soapClientMethods[\"" + s +
"\"]);};";
(global.eval) ? global.eval(scriptText) : eval(scriptText);
(global.eval) ? global.eval(("SOAPClient." + s + " = _" + s)) : eval(("SOAPClient." + s + " = _" + s));
}
}
}
}
xmlHttp.send(null);
}
}
SOAPClient._processInputs = function (inputs, messages, types, complexTypes, params)
{
for (var input = 0; input < inputs.length; input++)
{
var mName = inputs[input].getAttribute("message").split(':')[1];
var parts = null;
for (var message = 0; message < messages.length && parts==null; message++)
{
if (mName == messages[message].getAttribute("name"))
{
parts = SOAPClient._getElementsByTagName(messages[message], "part");
for (var part = 0; part < parts.length; part++)
{
var pName = parts[part].getAttribute("name");
if (varType = parts[part].getAttribute("type"))
{
var tmp = null;
var varType = varType.split(':')[1];
tmp = SOAPClient._makeVariable(pName, varType, tmp, null, params);
params[pName] = tmp;
}
else
{
var inElmName = parts[part].getAttribute("element").split(':')[1];
var schema = SOAPClient._getElementsByTagName( types, "schema")[0];
var typeElements = SOAPClient._getElementsByTagName(schema, "element");
var stop = false;
for (var element = 0; element < typeElements.length && !stop; element++)
{
if (typeElements[element].getAttribute("name") == inElmName)
{
var scTypes = typeElements[element].childNodes; //simple or complextype, (n)ever seen any simple examples?
for (var scType=0; scType < scTypes.length && !stop; scType++)
{
if ((scTypes[scType].localName
&& (scTypes[scType].localName == "complexType" || scTypes[scType].localName == "simpleType"))
|| (scTypes[scType].nodeName &&
( scTypes[scType].nodeName.split(':')[1] == "complexType" || scTypes[scType].nodeName.split(':')[1] == "simpleType")))
{
SOAPClient._parseType(scTypes[scType], complexTypes, null, params);
stop = true; //break
}
}
}
}
}
}
}
}
}
}
SOAPClient._parseType = function(scType, complexTypes, o, params )
{
var tmp = null;
if (scType.hasChildNodes())
{
//TODO localName
var egcsa = null; //element, group, choice, sequence, any
var elements = scType.childNodes;
for (var element=0; element < elements.length && egcsa == null; element++)
{
var elName = (elements[element].localName) ? elements[element].localName : elements[element].nodeName.split(":")[1];
if (elName == "element"
|| elName == "sequence"
|| elName == "group"
|| elName == "choice"
|| elName == "any"
)
{
egcsa = elements[element].childNodes;
}
}
for (var elmEgcsa=0; elmEgcsa < egcsa.length; elmEgcsa++)
{
var egcsaName = (egcsa[elmEgcsa].localName) ? egcsa[elmEgcsa].localName : egcsa[elmEgcsa].nodeName.split(':')[1];
if (egcsaName == "element" )
{
var varName = egcsa[elmEgcsa].getAttribute("name");
var varType = egcsa[elmEgcsa].getAttribute("type").split(':')[1];
var varMinOcc = egcsa[elmEgcsa].getAttribute("minOccurs");
var varMaxOcc = egcsa[elmEgcsa].getAttribute("maxOccurs");
tmp = SOAPClient._makeVariable(varName, varType, tmp, o, complexTypes, params);
}
}
}
//tmp == null void soap call
if (o == null && tmp != null) params[varName] = tmp;
}
SOAPClient._makeVariable = function(varName, varType, tmp, o, complexTypes, params)
{
if (varType.toLowerCase().indexOf("arrayof") == 0) // starts width
{
var aType = varType.substring(7, varType.length);
if(aType.indexOf('_') >-1)
{
//Axis ArrayOf_xsd_bla bla and ArrayOf_soapenc_bla bla
//for native array?s
aType = aType.substring(aType.lastIndexOf('_') + 1, varType.length);
}
tmp = SOAPClient._getNativeForStringType(aType);
tmp.isAArray = true;
tmp.typeName = aType;
if (o == null && typeof(tmp) == "object")
{
//We need to determin the nature of the complextype
SOAPClient._findAndParseComplexType(complexTypes, tmp, aType, params);
}
else
{
if (o != null)
{
(global.eval) ? global.eval("o." + varName + " = tmp") : eval("o." + varName + " = tmp");
}
}
}
else
{
tmp = SOAPClient._getNativeForStringType(varType);
tmp.typeName = varType;
if (o == null && typeof(tmp) == "object")
{
tmp.isAArray = false;
//mind: it's recursive
SOAPClient._findAndParseComplexType(complexTypes, tmp, varType, params);
}
else
{
if (o != null)
{
(global.eval) ? global.eval("o." + varName + " = tmp") : eval("o." + varName + " = tmp");
}
}
}
return tmp;
}
SOAPClient._findAndParseComplexType = function (complexTypes, o, objectName, params)
{
for (var complexType = 0; complexType < complexTypes.length; complexType++)
{
if (objectName == complexTypes[complexType].getAttribute("name"))
{
//mind: it's recursive, to complex types could blow up the browser!
SOAPClient._parseType(complexTypes[complexType], complexTypes, o, params);
}
}
}
SOAPClient._getNativeForStringType = function (type)
{
var o = null;
switch (type)
{
case "string": o = new String("");break;
case "gYearMonth": o = new String("");break;
case "gYear": o = new String("");break;
case "gMonthDay": o = new String("");break;
case "gDay": o = new String("");break;
case "gMonth": o = new String("");break;
case "hexBinary": o = new String("");break;
case "anyURI": o = new String("");break;
case "QName": o = new String("");break;
case "NOTATION": o = new String("");break;
case "boolean": o = new Boolean(true);break;
case "decimal": o = new Number(0);break;
case "float": o = new Number(0.0);break;
case "double": o = new Number(0E00);break;
case "duration": o = new Number(0);break;
case "dateTime": o = new Date();break;
case "time": o = new Time();break;
case "date": o = new Date();break;
case "base64Binary": o = new Number(0);break;
case "int": o = new Number(0);break;
case "long": o = new Number(0);break;
case "integer": o = new Number(0);break;
case "nonPositiveInteger": o = new Number(-1);break;
case "negativeInteger": o = new Number(-1);break;
case "short": o = new Number(0);break;
case "byte": o = new Number(0);break;
case "nonNegativeInteger": o = new Number(0);break;
case "unsignedLong": o = new Number(0);break;
case "unsignedInt": o = new Number(0);break;
case "unsignedShort": o = new Number(0);break;
case "unsignedByte": o = new Number(0);break;
case "positiveInteger": o = new Number(0);break;
default: o = new Object();break;
}
return o;
}
SOAPClient.invoke = function(url, method, parameters, async, callback)
{
if(async)
SOAPClient._loadWsdl(url, method, parameters, async, callback);
else
return SOAPClient._loadWsdl(url, method, parameters, async, callback);
}
// private: wsdl cache
SOAPClient_cacheWsdl = new Array();
// private: invoke async
SOAPClient._loadWsdl = function(url, method, parameters, async, callback)
{
// load from cache?
var wsdl = SOAPClient_cacheWsdl[url];
if(wsdl + "" != "" && wsdl + "" != "undefined")
return SOAPClient._sendSoapRequest(url, method, parameters, async, callback, wsdl);
// get wsdl
var xmlHttp = SOAPClient._getXmlHttp();
xmlHttp.open("GET", ((_wsdl_url + "" != "undefined") ? _wsdl_url : url+ "?wsdl"), async);
if(async)
{
xmlHttp.onreadystatechange = function()
{
if(xmlHttp.readyState == 4)
SOAPClient._onLoadWsdl(url, method, parameters, async, callback, xmlHttp);
}
}
xmlHttp.send(null);
if (!async)
return SOAPClient._onLoadWsdl(url, method, parameters, async, callback, xmlHttp);
}
SOAPClient._onLoadWsdl = function(url, method, parameters, async, callback, req)
{
var wsdl = req.responseXML;
SOAPClient_cacheWsdl[url] = wsdl; // save a copy in cache
return SOAPClient._sendSoapRequest(url, method, parameters, async, callback, wsdl);
}
SOAPClient._sendSoapRequest = function(url, method, parameters, async, callback, wsdl)
{
// get namespace
var ns = (wsdl.documentElement.attributes["targetNamespace"] + "" == "undefined") ? wsdl.documentElement.attributes.getNamedItem("targetNamespace").nodeValue : wsdl.documentElement.attributes["targetNamespace"].value;
// build SOAP request
var sr =
"<?xml version=\"1.0\" encoding=\"utf-8\"?>" +
"<soap:Envelope " +
"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>" +
"<" + method + " xmlns=\"" + ns + "\">" +
parameters.toXml() +
"</" + method + "></soap:Body></soap:Envelope>";
// send request
var xmlHttp = SOAPClient._getXmlHttp();
xmlHttp.open("POST", url, async);
var soapaction = ((ns.lastIndexOf("/") != ns.length - 1) ? ns + "/" : ns) + method;
xmlHttp.setRequestHeader("SOAPAction", soapaction);
xmlHttp.setRequestHeader("Content-Type", "text/xml; charset=utf-8");
if(async)
{
xmlHttp.onreadystatechange = function()
{
if(xmlHttp.readyState == 4)
SOAPClient._onSendSoapRequest(method, async, callback, wsdl, xmlHttp);
}
}
xmlHttp.send(sr);
if (!async)
return SOAPClient._onSendSoapRequest(method, async, callback, wsdl, xmlHttp);
}
SOAPClient._sendSoapRequest2 = function(url, method, parameters, async, callback, soapClientMethod)
{
// build SOAP request
var ns = soapClientMethod.namespace;
var sr =
"<?xml version=\"1.0\" encoding=\"utf-8\"?>" +
"<soap:Envelope " +
"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>" +
"<" + method + " xmlns=\"" + ns + "\">" +
parameters.toXml() +
"</" + method + "></soap:Body></soap:Envelope>";
// send request
var xmlHttp = SOAPClient._getXmlHttp();
xmlHttp.open("POST", url, async);
var soapaction = ((ns.lastIndexOf("/") != ns.length - 1) ? ns + "/" : ns) + method;
xmlHttp.setRequestHeader("SOAPAction", soapaction);
xmlHttp.setRequestHeader("Content-Type", "text/xml; charset=utf-8");
if(async)
{
xmlHttp.onreadystatechange = function()
{
if(xmlHttp.readyState == 4)
SOAPClient._processResponse(callback, xmlHttp, soapClientMethod);
}
}
xmlHttp.send(sr);
if (!async)
return SOAPClient._processResponse(null, xmlHttp, soapClientMethod);
}
SOAPClient._processResponse = function(callback, xmlHttp, soapClientMethod)
{
var soapR = xmlHttp.responseXML;
var result = new Array();
var o = {};
var i = 0;
for (p in soapClientMethod.paramsOut)
{
var results = SOAPClient._getElementsByTagName(soapR, p);
var value = null;
if (results.length>0)
{
if (soapClientMethod.paramsOut[p].isAArray)
{
value = new Array();
for (var a = 0; a < results.length; a++)
{
value[a] = SOAPClient._extractValue(results[a].childNodes[0], null, soapClientMethod.paramsOut[p].typeName) ;
}
}
else
{
value = SOAPClient._extractValue(results[0].childNodes[0], null, soapClientMethod.paramsOut[p].typeName) ;
}
} else {
if(req.responseXML.getElementsByTagName("faultcode").length > 0)
throw new Error(500, req.responseXML.getElementsByTagName("faultstring")[0].childNodes[0].nodeValue);
}
var scriptText = "o." + p + "= soapClientMethod.paramsOut[p]; result[" + i
+ "] = soapClientMethod.paramsOut[p]; result[" + i + "] = value; o." + p + " = value;";
(global.eval) ? global.eval(scriptText) : eval(scriptText);
i++;
}
if (callback != null) {
var scriptText = "callback(";
for (var rs = 0; rs < result.length; rs++ )
{
scriptText += "result[ " + rs + " ], ";
}
scriptText = scriptText.substring(0, scriptText.lastIndexOf(','));
scriptText += ");";
if (result.length>0)
(global.eval) ? global.eval(scriptText) : eval(scriptText);
}
if (result.length == 1) return result[0];
return o;
}
SOAPClient._onSendSoapRequest = function(method, async, callback, wsdl, req)
{
var o = null;
var nd = SOAPClient._getElementsByTagName(req.responseXML, method + "Result");
//if nothing is found, lets try method + Response...
if(nd.length == 0) nd = SOAPClient._getElementsByTagName(req.responseXML, method + "Response");
if(nd.length == 0) {
//still nothing, we've got a wsdl let's try to find it.
//caching should be added later
var nodes = req.responseXML.getElementsByTagName("ouput");
for (var h=0; h<nodes.length() && nd.length == 0;h++) {
var output = nodes[h];
if (output.nodeName="output" && (output.getAttribute("message") + "") != "undefined" ) {
var responseNS = output.getAttribute("message");
var response = responseNS.split(':')[responseNS.split(':').length - 1];
nd = SOAPClient._getElementsByTagName(req.responseXML, response);
}
}
}
if(nd.length == 0)
{
if(req.responseXML.getElementsByTagName("faultcode").length > 0)
{
if(async || callback)
o = new Error(500, req.responseXML.getElementsByTagName("faultstring")[0].childNodes[0].nodeValue);
else
throw new Error(500, req.responseXML.getElementsByTagName("faultstring")[0].childNodes[0].nodeValue);
}
}
else
o = SOAPClient._soapresult2object(nd[0], wsdl);
if(callback)
callback(o, req.responseXML);
if(!async)
return o;
}
// private: utils
SOAPClient._getElementsByTagName = function(document, tagName)
{
try
{
// trying to get node omitting any namespaces (latest versions of MSXML.XMLDocument)
var tmp = document.selectNodes(".//*[local-name()=\""+ tagName +"\"]");
if (tmp != null && tmp.length >0) return tmp;
}
catch (ex) {}
// old XML parser support
var aResult = document.getElementsByTagName(tagName);
// namespace and old DOM and ie
if (aResult.length >0) return aResult;
var i=0, oTemp;
for(i; i < document.childNodes.length; i++)
{
oTemp=document.childNodes[i];
if(oTemp.localName==tagName) aResults.push(oTemp);
}
return aResult;
}
SOAPClient._soapresult2object = function(node, wsdl)
{
return SOAPClient._node2object(node, wsdl);
}
SOAPClient._node2object = function(node, wsdl)
{
// null node
if(node == null)
return null;
// text node
if(node.nodeType == 3 || node.nodeType == 4)
return SOAPClient._extractValue(node, wsdl);
// leaf node
if (node.childNodes.length == 1 && (node.childNodes[0].nodeType == 3 || node.childNodes[0].nodeType == 4))
return SOAPClient._node2object(node.childNodes[0], wsdl);
var isarray = SOAPClient._getTypeFromWsdl(node.nodeName, wsdl).toLowerCase().indexOf("arrayof") != -1;
// object node
if(!isarray)
{
var obj = null;
if(node.hasChildNodes())
obj = new Object();
for(var i = 0; i < node.childNodes.length; i++)
{
var p = SOAPClient._node2object(node.childNodes[i], wsdl);
obj[node.childNodes[i].nodeName] = p;
}
return obj;
}
// list node
else
{
// create node ref
var l = new Array();
for(var i = 0; i < node.childNodes.length; i++)
l[l.length] = SOAPClient._node2object(node.childNodes[i], wsdl);
return l;
}
return null;
}
SOAPClient._extractValue = function(node, wsdl, type)
{
var value = node.nodeValue;
if (type == null)
type = SOAPClient._getTypeFromWsdl(node.parentNode.nodeName, wsdl).toLowerCase();
else type = "s:" + type;
switch(type)
{
default:
case "s:string":
return (value != null) ? value + "" : "";
case "s:boolean":
return value+"" == "true";
case "s:int":
case "s:long":
return (value != null) ? parseInt(value + "", 10) : 0;
case "s:double":
return (value != null) ? parseFloat(value + "") : 0;
case "s:datetime":
if(value == null)
return null;
else
{
value = value + "";
value = value.substring(0, value.lastIndexOf("."));
value = value.replace(/T/gi," ");
value = value.replace(/-/gi,"/");
var d = new Date();
d.setTime(Date.parse(value));
return d;
}
}
}
SOAPClient._getTypeFromWsdl = function(elementname, wsdl)
{
var ell = wsdl.getElementsByTagName("s:element"); // IE
if(ell.length == 0)
ell = wsdl.getElementsByTagName("element"); // MOZ
for(var i = 0; i < ell.length; i++)
{
if(ell[i].attributes["name"] + "" == "undefined") // IE
{
if(ell[i].attributes.getNamedItem("name") != null && ell[i].attributes.getNamedItem("name").nodeValue == elementname && ell[i].attributes.getNamedItem("type") != null)
return ell[i].attributes.getNamedItem("type").nodeValue;
}
else // MOZ
{
if(ell[i].attributes["name"] != null && ell[i].attributes["name"].value == elementname && ell[i].attributes["type"] != null)
return ell[i].attributes["type"].value;
}
}
return "";
}
// private: xmlhttp factory
SOAPClient._getXmlHttp = function()
{
try
{
if(window.XMLHttpRequest)
{
var req = new XMLHttpRequest();
// some versions of Moz do not support the readyState property and the onreadystate event so we patch it!
if(req.readyState == null)
{
req.readyState = 1;
req.addEventListener("load",
function()
{
req.readyState = 4;
if(typeof req.onreadystatechange == "function")
req.onreadystatechange();
},
false);
}
return req;
}
if(window.ActiveXObject)
return new ActiveXObject(SOAPClient._getXmlHttpProgID());
}
catch (ex) {}
throw new Error("Your browser does not support XmlHttp objects");
}
SOAPClient._getXmlHttpProgID = function()
{
if(SOAPClient._getXmlHttpProgID.progid)
return SOAPClient._getXmlHttpProgID.progid;
var progids = ["Msxml2.XMLHTTP.5.0", "Msxml2.XMLHTTP.4.0", "MSXML2.XMLHTTP.3.0", "MSXML2.XMLHTTP", "Microsoft.XMLHTTP"];
var o;
for(var i = 0; i < progids.length; i++)
{
try
{
o = new ActiveXObject(progids[i]);
return SOAPClient._getXmlHttpProgID.progid = progids[i];
}
catch (ex) {};
}
throw new Error("Could not find an installed XML parser");
}
-- modified at 8:24 Friday 11th August, 2006
|
|
|
|
|
Can you provide a server side example of usage?
Thanks
dadgad
|
|
|
|
|
You've made a typo in the SOAPClient._loadWsdl method - you've put wdsl instead of wsdl.
// private: invoke async
SOAPClient._loadWsdl = function(url, method, parameters, async, callback)
{
// load from cache?
var wsdl = SOAPClient_cacheWsdl[url];
if(wsdl + "" != "" && wsdl + "" != "undefined")
return SOAPClient._sendSoapRequest(url, method, parameters, async, callback, wsdl);
// get wsdl
var xmlHttp = SOAPClient._getXmlHttp();
xmlHttp.open("GET", ((_wdsl_url + "" != "undefined") ? _wdsl_url : url+ "?wdsl"), async); <--- Error here.
I'd post the correct code, but I've changed all the instances of the mis-spelled word, even in the variables.
|
|
|
|
|
Thanks manzanotti,
I´ve changed the code as you suggested.
Regards, Marco.
|
|
|
|
|
with your modification to the soapclient, if i have the wsdl in my own client domain..how do i modify modify your source? or maybe the question is is it possible to add a method to pass the wsdl file?
|
|
|
|
|
I am calling a remote webservice that returns a DataSet
When I use the code you supplied in my Atlas application, it throws an exception as this type (function) is not , so I tried to add case for the DataSet but I just cant figureout how to handle it
case "function":
alert(o.toString());
'
'
'
'
case "function":
type = "DataSet"; break;
It then alerted some functions but I really dont know how to use them, Any way to handle DataSet??
|
|
|
|
|
Hello mashry68,
Can you send/post a WSDL example or link?
Regards, Marco.
|
|
|
|
|
I had this question too....
My application like this:
var url = "http://localhost/DiningRoom/webservices/ws_Products_Sort.asmx";
var pl = new SOAPClientParameters();
//pl.add("Name","Jack");
SOAPClient.invoke(url,"getProductSort",pl,true,ProductSortBack);
function ProductSortBack(val)
{
//the result is type of DataSet How can i use them .....
//help me pls ..thanks very much
}
[WebMethod]
public DataSet getProductSort()
{
string ColumenList = "IID,OID,ID,CName";
string tbName = "Product_Sort";
string Condition = "";
string OrderBy = "IID,OID ASC";
return db.getDataSet(ColumenList,tbName,Condition,OrderBy,"");
}
|
|
|
|
|
soapclient.js does not work when used in the same page as the latest version of prototype.js, see http://prototype.conio.net/
That is very unfortunate! I'll be back later to see what must be done to resolve this...
-- modified at 15:47 Thursday 22nd June, 2006
|
|
|
|
|
OK, to fix this open soapclient.js and go to line 93-94 and replace with:
<br />
default:<br />
-- modified at 17:47 Thursday 22nd June, 2006
And go to line 18 and change to:
<br />
this.toXml = function()<br />
{<br />
var xml = "";<br />
for(var p in _pl) {<br />
switch(typeof(_pl[p])) {<br />
case "string":<br />
case "number":<br />
case "boolean":<br />
case "object": <br />
xml += "<" + p + ">" + SOAPClientParameters._serialize(_pl[p]) + "</" + p + ">";<br />
break;<br />
default:<br />
break;<br />
}<br />
}<br />
return xml; <br />
}<br />
Only _serialize() if a serializable type!!
|
|
|
|
|
small correction to the previous post: for the second block (line 18),
use this:
-----------------------------------
this.toXml = function()
{
var xml = "";
for(var p in _pl) {
switch(typeof(_pl[p])) {
case "string":
case "number":
case "boolean":
case "object":
xml += "<" + p + ">" + SOAPClientParameters._serialize(_pl[p]) + "</" + p + ">";
break;
default:
break;
}
}
return xml;
}
----------------------------------
(that is, the xml node has to be closed!)
this refers to the soapclient version 2.1
http://www.guru4.net/articoli/javascript-soap-client/en/
Thanks for the great work!
|
|
|
|
|
According to http://www-128.ibm.com/developerworks/webservices/library/ws-whichwsdl/ there are several styles of WSDL: rpc/encoded, rpc/literal, document/literal and document/literal wrapped.
Only the ones with literal are WS-I compliant so reachable from mobile devices for example.
My question is does soapclient.js handle all types of WSDL equally well? If not which are the preferred ones.
Super library by the way!
|
|
|
|
|