Call SOAP-XML Web Services With jQuery Ajax

jQuery: Write less, do more

jQuery: Write less, do more

jQuery‘s popularity has really exploded over last few years. What really stands out about jQuery is its clear and consise JavaScript library. Other things I’ve come to appreciate over time is its deep functionality and completely non-intrusive configuration. Recently, to improve the responsiveness of my user interfaces, I decided to use jQuery’s Ajax to call SOAP-XML web services directly. I struggled to find good information on how this can be done. There are a lot of good examples on the web that demonstrate how to use JSON web services from jQuery Ajax, but almost none for SOAP-XML web services.

.NET Web Service Operation Definition

.NET Web Service Operation Definition

Before you can call the web service from client script you need to obtain the web service operation’s WSDL. If you’re using a .NET web service, you can just point your browser to the web service’s URL, and click on the operation’s name.

The example web service operation I’m using, SaveProduct, has the following schema:

POST /ProductService.asmx HTTP/1.1
Host: localhost
Content-Type: text/xml; charset=utf-8
Content-Length: length
SOAPAction: "http://sh.inobido.com/SaveProduct"

<?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>
<SaveProduct xmlns="http://sh.inobido.com/">
<productID>int</productID>
<productName>string</productName>
<manufactureDate>dateTime</manufactureDate>
</SaveProduct>
</soap:Body>
</soap:Envelope>

The method that will contact this operation looks like this:

var productServiceUrl = 'http://localhost:57299/ProductService.asmx?op=SaveProduct'; // Preferably write this out from server side

function beginSaveProduct(productID, productName, manufactureDate)
{
var soapMessage =
'<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> \
<SaveProduct xmlns="http://sh.inobido.com/"> \
<productID>' + productID + '</productID> \
<productName>' + productName + '</productName> \
<manufactureDate>' + manufactureDate + '</manufactureDate> \
</SaveProduct> \
</soap:Body> \
</soap:Envelope>';

$.ajax({
url: productServiceUrl,
type: "POST",
dataType: "xml",
data: soapMessage,
complete: endSaveProduct,
contentType: "text/xml; charset=\"utf-8\""
});

return false;
}

function endSaveProduct(xmlHttpRequest, status)
{
 $(xmlHttpRequest.responseXML)
    .find('SaveProductResult')
    .each(function()
 {
   var name = $(this).find('Name').text();
 });
}

In order to call the web service, we need to supply an XML message that match the operation definition specified by the web service’s WSDL. With the operation’s schema already in hand, all that is required is to exchange the type names for the operation’s paramaters, with their actual values. The variable soapMessage contains the complete XML message that we’re going to send to the web service.

To make an Ajax request with jQuery you use the ajax method found on the jQuery object. The $/dollar sign is an alias for jQuery, the actual name of the object; the symbol just provides a shortcut to the jQuery object. The ajax method provides a wide range of options to manage low level Ajax tasks, but we’ll only cover the ones we’ve used here:

  1. url: Should be pretty obvious. This is the web service’s end-point URL. All I’ve done is instead of hard coding it, I assigned the URL to the variable productServiceUrl when I create the page’s HTML from the server side.
  2. type: The type of request we’re sending. jQuery uses “GET” by default. If you quickly take a look again at the SaveProduct operation’s definition, you will notice that on the 1st line it specifies that requests should use the “POST” HTTP method.
  3. dataType: The type of data that the response will send back. The usual types are available like html, json, etc. If you’re working with a SOAP web service, you need to specify the xml dataType.
  4. data: Another easy one. This is the actual data, as XML text, you will be sending to the web service.
  5. complete: The callback delegate that will be executed when the request completes. The callback method must implement the following signature: function (XMLHttpRequest, textStatus) {  /* Code goes here */ } .
  6. contentType: A string representing the MIME content type of the request, in this case it’s “text/xml” because we’re working with a SOAP web service that expects XML data.

Now you’re ready to send your XML data off to the web service. Once the server finishes processing the request, the endSaveProduct method gets called. To process the XML response in jQuery, you need to know the SOAP reponse’s schema/definition. The SaveProduct web method has the following schema:

HTTP/1.1 200 OK
Content-Type: text/xml; charset=utf-8
Content-Length: length

<?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>
    <SaveProductResponse xmlns="http://sh.inobido.com/">
      <SaveProductResult>
        <ID>int</ID>
        <Name>string</Name>
        <ManufactureDate>dateTime</ManufactureDate>
      </SaveProductResult>
    </SaveProductResponse>
  </soap:Body>
</soap:Envelope>

From this schema it should be clear that the web method SaveProduct sends back the Product object that was saved. You will find the XML document/data on the xmlHttpRequest parameter’s responseXML property. From here you can use the usual jQuery methods to traverse the XML document’s nodes to extract the data.

About these ads

48 Comments on “Call SOAP-XML Web Services With jQuery Ajax”

  1. kurono says:

    Excellent article, just what i was looking for!

    Thanks.

  2. Su says:

    Brilliant! Thanks so much for writing this tutorial, it’s very helpful.

  3. ww says:

    Thanks !
    But I have a good idear than it!

  4. Mohammed Abdur Rafay says:

    Getting and error

    xmlHttpRequest: not defined

    Need an urgent suggestion

    • openlandscape says:

      When do you get this error? Can you please post the code where the error occurs. What browser are you using?

  5. pepe says:

    How i write the SOAPAction?

  6. Sid DeLuca says:

    I used the following to add the SOAPAction value:

    beforeSend: function(xhr) { xhr.setRequestHeader(‘SOAPAction’, ‘(value from line 5 of request schema above)’); },

    Insert the snippet above into your $.ajax call, and modify the value to the appropriate SOAPAction.

    Thank you Mr. du Preez for the article!

  7. [...] Call SOAP-XML Web Services openlandscape.wordpress.com [...]

  8. [...] to call the web service we created in my last post. There was a good article that you can find here which explains the details of writing jQuery/AJAX code to call a SOAP web [...]

  9. ankit malik says:

    I get a parsererror, when i try to post stuff, is it due to a malformed soap req or is there an ajax issue
    here is my soap request
    var soapMessage =
    ‘ \
    \
    \
    \
    amalik \
    #Billrizer1 \
    \
    \

    • openlandscape says:

      Hi,

      What is the exact error message you’re getting? Can you access the web service with something else other than jQuery Ajax (SoapUI, Visual Studio, .NET WSDL web service generator)?

  10. Jypyx says:

    So nice, could not find a more perfect example than yours.
    Thank you!

  11. Hans van Meer says:

    there seems to be a ) missing in the function: endSaveProduct. Also – when I add the ), firefox is complaining that this function is not defined. Any thoughts? Looks great, just can’t get it to work yet.

    • openlandscape says:

      Hi Hans,

      Thanks for spotting that. I believe a “);” is in fact missing. I made the corrections in line 35. Let me know if it works now.

  12. Paxton Brewer says:

    Excellent article. It’s hard to believe that there isn’t more information about this out there.

    There is one very important issue that you haven’t covered, and I’m wondering if you have a solution. JavaScript has cross-domain loading restrictions, meaning you can’t load data from a domain outside of your own. So I can’t use this solution to call SOAP data from an external SOAP service.

    I have been using a PHP proxy on my server, but this seems a little clumsy. Do you have another solution?

    • openlandscape says:

      Hi Paxton,

      Cross domain scripting is solved by doing a prefetch for the given URL to the server. The server then responds with the Access-Control-Allow-Origin with the client’s host domain & Access-Control-Request-Method with the allowed HTTP method-verbs. So both the browser & server has to support this process, in order for it to work. Check this page to get an idea of how it will work. Also check the W3C standards doc.

      I haven’t done this with an SOAP web service, so I’m not able to give you an indication of what you’ll have to do to get your web service’s underlying HTTP to support this mechanism.

  13. Hello, thanks for the article. I am trying to do a soap ajax request as you do.. Here is my service:
    POST /_vti_bin/QuickLinks.asmx HTTP/1.1
    Host: myintracomm-design.ec.europa.eu
    Content-Type: text/xml; charset=utf-8
    Content-Length: length
    SOAPAction: “http://ec.europa.eu/GetSuggestions”

    string
    int

    (although after this box there is one similar one but instead of the coode <GetSuggestions .. there is:

    string
    string

    Anyway, I write my JS code:

    var productServiceUrl = ‘http://blabla-design.com/_vti_bin/QuickLinks.asmx?op=GetSuggestions’;

    function LoadData() {
    var soapEnv =
    ‘ \
    \
    \
    \
    ‘ + string + ‘ \
    ‘ + string + ‘ \
    \
    \
    \
    ‘;

    $jQuery.ajax({
    url: productServiceUrl,
    type: “POST”,
    dataType: “xml”,
    data: soapEnv,
    complete: OnLinksFetched,
    contentType: “text/xml; charset=\”utf-8\””
    });
    }

    function OnLinksFetched(xmlHttpRequest, status)
    {
    $jQuery(xmlHttpRequest.responseXML)
    .find(‘GetSuggestionsResult’)
    .each(function() {
    var name = $jQuery(this).find(‘Name’).text();
    $jQuery(“#links”).append(name);
    });}

    but I get error:

    string is not defined …

  14. Sorry, apparently all my tags are converted from the system. Here is the web service again:

    HTTP/1.1 200 OK
    Content-Type: text/xml; charset=utf-8
    Content-Length: length

    ?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
    GetSuggestionsResponse xmlns=”http://ec.europa.eu/”
    GetSuggestionsResult
    stringstring/string
    stringstring/string
    /GetSuggestionsResult
    /GetSuggestionsResponse
    /soap:Body
    /soap:Envelope

  15. Rob says:

    I’m getting a parse error when I use data type in my SOAP message as “xml”. Anyone else having this issue?

  16. Ro says:

    Hi, I’m trying to start using jquery and invoke a service. I followed this excellent article, but didn’t work.

    var wsdl = “http://127.0.0.1:5151/teams?wsdl”;
    var soapMessage = ”;

    $.ajax({
    url: “http://127.0.0.1:5151/teams?wsdl”,
    type: “POST”,
    dataType: “xml; charset=’utf-8′”,
    data: soapMessage,
    complete: result,
    error: error,
    contentType: “text/xml”
    });
    in the error function I have an alert(error).

    I get an undefined error. While debugging, I realized that jquery aborts the operation with no apparent reason.

    I tried double quoting the utf-8 and got the same result.
    I tried with the tag before the envelope tag and got the same result: undefined.
    I tried url: “http://127.0.0.1:5151/teams/teams”, that is, without specifying the actual wsdl and same thing: undefined.

    Funny thing, using the same exact url and soap message, it works perfectly in the apache tcpMon.

    The error is not very descriptive, it just gives me the error status and the error is undefined. When I wasn’t using error:error, just complete:result, I used to do an alert(xmlHttpRequest.responseXML). Same thing: undefined.

    thanks in advance.

    • Ro says:

      var soapMessage = “”;

      (it didn’t show up in the original comment)

      • Ro says:

        var soapMessage = ‘….S:Envelope xmlns:S=”http://schemas.xmlsoap.org/soap/envelope/” ….S:Body…. ns2:getTeams xmlns:ns2=”http://team.ch01/” /…. /S:Body…. /S:Envelope’

    • jmk201 says:

      Hello,
      did you get this to work? I followed this article but I get an undefined error too. Any help would appreciated.
      thanks

  17. Ajith says:

    This is exactly what I was looking for. Thanks so much! I was stuck with not able to call my Java webservice using jQuery. I followed this article and I could get it to work, finally! Thanks again!

  18. Maya says:

    Hi openlandscape ,
    I have some issue with calling my soap web service from jquery.Please help me to find out the solution . here is my post
    http://stackoverflow.com/questions/9586709/how-to-call-a-soap-web-service-from-jquery

  19. thera says:

    Thank you so much for this article =)

    But i’m having an issue in trying to get a node value from the returned xml response. I’m using jQuery 1.6

    alert 1 shows the complete xml response I receive
    but alert 2 shows [object Document]
    alert 3 never pops up

    Please do give me hand to figure this out. Thanks in advance

    function soapHanlder(jqXHR, status){
    alert(jqXHR.responseText);//———————alert 1
    alert(jqXHR.responseXML);//———————alert 2

    $(jqXHR.responseXML)
    .find(‘myNodeName’)
    .each(function()
    {
    var name = $(this).find(‘myNodeName’).text();
    alert(name);//———————alert 3

    });
    }

  20. Mohit kumar says:

    Really a good article ever made…
    thank you very much

  21. Arun Kishore P says:

    hi friends,
    I can call the webservice by sending the soap xml request in IE browser but it is not working in mozilla firefox and safari. i followed only the above procedure which you given at top. can u give any quick suggestions to overcome this problem.

    when i was executed in IE, webservice executed fine but in mozilla firefox and safari it giving status 404 error message. THANKS for advance.

  22. Karen says:

    Thank you very much, just what I needed!

  23. Mahmod says:

    Thanks, its an interesting read.

    I am sending a soap request with data:xml and Content-Type:text/xml and getting following response:

    –MIME_boundary
    Content-Type: text/xml; charset=utf-8
    Content-Transfer-Encoding: binary
    Content-ID:

    ………….
    –MIME_boundary
    Content-Type: application/pdf
    Content-Transfer-Encoding: binary

    …. pdf raw data …..

    As i understand the reponse is a multipart with an attachment … but how can i extract the pdf raw data to build this pdf? Thanx for any help.

  24. Mahmod says:

    the complete code could not go through in the previous comment .. here a link http://stackoverflow.com/questions/12284687/jquery-ajax-soap-multipart-response-pdf

  25. Ranga says:

    Hi All,
    I am getting the error message “Origin http://192.168.0.131 is not allowed by Access-Control-Allow-Origin.”

    Can any one help me?

    • openlandscape says:

      It sounds like you’re doing cross domain calls (i.e. the origin of the Ajax request is from a server different to the one that sends the response). You have to add the following headers to the server’s responses to enable prefetching:
      Access-Control-Allow-Origin: *
      Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS

      The current Allow-Origin that I’ve added will allow access from requests on anywhere. So make sure you change this with specific addresses in production.

      Although not directly applicable, my post on ServiceStack discusses this situation and will give you a good idea what’s required. Read the section “Create a Web Service Host with AppHostBase”…

  26. jmk201 says:

    can all SOAP web services be invoked by jquery?

    I am trying to call a SOAP web services http://wd.air-trak.com/ATAuthenticationWS/service.asmx?op=GetKey

    what will my productServiceUrl be?
    please help!!

  27. Tien Thanh says:

    Hi, thanks so much for your post, but can you post a entry about server side to prossess a soap message request from client?

  28. Me says:

    I want to know what is the difference between a. asmx file and. wsdl ?? thx

  29. In the case that you want to get the data from the invoke. Let’s say you want to get the information when you KNOW the productID, and you invoke the search for productID 12345. What would be the process to GET information from the SOAP service from products that have been saved to the DB. This tutorial shows how to save products, but how do you GET product information from the SOAP service.

  30. Rauf says:

    Just perfect!!! thanks.
    Can you help me i am getting following error:
    “the server responded with a status of 403(forbidded)”

    I am very new to web services so my question may be silly

  31. Maximaus says:

    Thank you for this tutorial.
    Can this code work with jquery mobile?
    i want to use web services in a mobile application how can i do that?
    Thanks :)

  32. Alireza says:

    This was perfect for me!!!! thank you soooooooooooo much

  33. […] if you would like to call a webservice which returns an XML format, why not have a read at this article: http://openlandscape.net/2009/09/25/call-soap-xm-web-services-with-jquery-ajax/ […]


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.