I have for a few weeks now been trying to get one of my jQuery AJAX SOAP based cross domain web service to work from a jQuery plugin I have written for one of my customers. Most of the research I did seemed to indicate that it was not possible because CORS or Cross Origin Resource Sharing would only allow jasonP (GET) type calls.
I have finally figured how to make it work and thought I would share what I had to do.
The first thing to understand is that in a CORS aware browser, where the server is in another domain, anything other that a GET (amongst other parameters) will result in what is called a preflight check. What this means is that the browser will ask the server for a list of options that it is allowed to perform. Unless the server returns the exact list of options to allow a SOAP based web service the call will fail even before the actual request is made.
What you need to do is to make the web server (in my example it's IIS7.5) return the correct list of options.
You do this by configuring the web.config file in the inetpub\wwwroot folder (if you don't have one just create it and copy the following into it).
My web.config file looks like this.
Important everything is case sensitive once I realized this everything just worked as expected.
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.webServer>
<httpProtocol>
<customHeaders>
<add name="Access-Control-Allow-Origin" value="*" />
<add name="Access-Control-Allow-Methods" value="POST, GET, OPTIONS, PUT, DELETE" />
<add name="Access-Control-Allow-Headers" value="content-type,soapaction,x-requested-with" />
</customHeaders>
</httpProtocol>
<handlers accessPolicy="Read, Execute, Script" />
</system.webServer>
</configuration>
My jQuery AJAX code looks like this.
var getNextJobId = function()
{
var se = '';
se = se + '<?xml version="1.0" encoding="UTF-8" standalone="no"?>';
se = se + '<soap-env:Envelope xmlns:soap-env="http://www.w3.org/2003/05/soap-envelope">';
se = se + '<soap-env:Body>';
se = se + '<ebas:getNextJobIdRequest xmlns:ebas="http://www.ebasetech.com">';
se = se + '<ebas:ORGCODE>' + plugin.settings.orgcode + '</ebas:ORGCODE>';
se = se + '</ebas:getNextJobIdRequest>';
se = se + '</soap-env:Body>';
se = se + '</soap-env:Envelope>';
$.ajax(
{
url: params.webserviceTargetUrl,
beforeSend: function(xhr)
{
xhr.setRequestHeader("SOAPAction", "getNextJobId");
},
type: "POST",
dataType: "xml",
data: se,
crossDomain: true,
headers: {"X-Requested-With": "XMLHttpRequest"},
async: false,
success: function(xml)
{
params.jobId = $(xml).find("ebas\:JOBID").text();
},
failure: function(xml)
{
params.webserviceFailure = $(xml).text();
},
contentType: "charset=UTF-8"
});
}