Since the native SOAP interface was removed from Gecko 1.9, those stuck speaking to SOAP APIs need a new place to turn. After some experimentation, the following seems to be the best way to speak SOAP in XULRunner.
Several alternatives were considered:
- soapclient 2.4 - This library contains a few JavaScript mistakes but nevertheless seems (fairly) widely used, mature and tested. It requires servers to support WSDL which took it out of the running.
- XULRunner 1.8.* - Using an old XULRunner is certainly an option but brings up a host of speed, stability and memory issues.
- Manual implementation - The author doesn't know enough about SOAP to implement a robust client in an afternoon.
The best solution proved to be jqSOAPClient. This library doesn't require a WSDL. Though jQuery is listed as a dependency, it can be worked around easily. (There is a diff below.)
You'll need:
Making a SOAP call
var url = 'http://example.com/soap/'; var ns = 'http://example.com/soap/namespace'; var method = 'foo'; var params = { 'foo': 'bar', 'baz': 'bang' }; var callback = function(obj) { Components.utils.reportError(obj.toSource()); }; SOAPClient.Proxy = url; var body = new SOAPObject(method); body.ns = ns; for (var k in params) { body.appendChild(new SOAPObject(k).val(params[k])); } var req = new SOAPRequest(url, body); req.Action = ns + '#' + method; SOAPClient.SendRequest(req, callback);
Diff between jqSOAPClient.js and saSOAPClient.js
42c42 < var jsOut = $.xmlToJSON(xData.responseXML); --- > var jsOut = XMLObjectifier.xmlToJSON(xData.responseXML); 46,60c46,62 < $.ajax({ < type: "POST", < url: SOAPClient.Proxy, < dataType: "xml", < processData: false, < data: content, < complete: getResponse, < contentType: SOAPClient.ContentType + "; charset=\"" + SOAPClient.CharSet + "\"", < beforeSend: function(req) { < req.setRequestHeader("Method", "POST"); < req.setRequestHeader("Content-Length", SOAPClient.ContentLength); < req.setRequestHeader("SOAPServer", SOAPClient.SOAPServer); < req.setRequestHeader("SOAPAction", soapReq.Action); < } < }); --- > var xhr = new XMLHttpRequest(); > xhr.mozBackgroundRequest = true; > xhr.open('POST', SOAPClient.Proxy, true); > xhr.onreadystatechange = function() { > if (4 != xhr.readyState) { return; } > getResponse(xhr); > }; > var headers = { > 'Method': 'POST', > 'Content-Type': SOAPClient.ContentType + '; charset="' + > SOAPClient.CharSet + '"', > 'Content-Length': SOAPClient.ContentLength, > 'SOAPServer': SOAPClient.SOAPServer, > 'SOAPAction': soapReq.Action > }; > for (var h in headers) { xhr.setRequestHeader(h, headers[h]); } > xhr.send(content);