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);