ChatGPT解决这个技术问题 Extra ChatGPT

Simplest SOAP example

What is the simplest SOAP example using Javascript?

To be as useful as possible, the answer should:

Be functional (in other words actually work)

Send at least one parameter that can be set elsewhere in the code

Process at least one result value that can be read elsewhere in the code

Work with most modern browser versions

Be as clear and as short as possible, without using an external library

Being simple and clear may conflict with not using an external library. Do you really want to write your own WSDL -> JS class converter?
I have a question: if I saw this question as the first person I would expect it to be downvoted with comments like "show some code, this is not 'rent a coder'". Nothing personal, Thomas :) But I cant understand how the community decides whats good and bad.
Hey no worries. I guess the point of the question is that there are lots of ways of writing a SOAP client using JavaScript. Many of them are ugly, so I was hoping for some ideas on keeping it clean.
@dan it's because 1. this question is rather old, there were still a lot of fundamental questions beging asked which by tradition have many upvotes, 2. it describes a rather simple problem, so it probably tends to attract new users who might vote by the principle of "hey I wanna know that too!" instead of "hey, this question shows research effort. it is useful and clear!". As the question lacks this in my opinion, I downvoted it. Nothing personal too :D
@ThomasBratt I will probably continue this on meta, but those type of questions deserve a chance. It is the ideal question for a descent library of reference or knowledge base. But just maybe the accepted answer also deserves an incentive for the extra legwork? There is still nothing more accepted than SO, so where else? Even SO tried and toyed with the idea of building a documentation site - and failed. Nothing to replace SO ...

S
Sergio Muriel

This is the simplest JavaScript SOAP Client I can create.

<html>
<head>
    <title>SOAP JavaScript Client Test</title>
    <script type="text/javascript">
        function soap() {
            var xmlhttp = new XMLHttpRequest();
            xmlhttp.open('POST', 'https://somesoapurl.com/', true);

            // build SOAP request
            var sr =
                '<?xml version="1.0" encoding="utf-8"?>' +
                '<soapenv:Envelope ' + 
                    'xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" ' +
                    'xmlns:api="http://127.0.0.1/Integrics/Enswitch/API" ' +
                    'xmlns:xsd="http://www.w3.org/2001/XMLSchema" ' +
                    'xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">' +
                    '<soapenv:Body>' +
                        '<api:some_api_call soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">' +
                            '<username xsi:type="xsd:string">login_username</username>' +
                            '<password xsi:type="xsd:string">password</password>' +
                        '</api:some_api_call>' +
                    '</soapenv:Body>' +
                '</soapenv:Envelope>';

            xmlhttp.onreadystatechange = function () {
                if (xmlhttp.readyState == 4) {
                    if (xmlhttp.status == 200) {
                        alert(xmlhttp.responseText);
                        // alert('done. use firebug/console to see network response');
                    }
                }
            }
            // Send the POST request
            xmlhttp.setRequestHeader('Content-Type', 'text/xml');
            xmlhttp.send(sr);
            // send request
            // ...
        }
    </script>
</head>
<body>
    <form name="Demo" action="" method="post">
        <div>
            <input type="button" value="Soap" onclick="soap();" />
        </div>
    </form>
</body>
</html> <!-- typo -->

What about sending a ? I tried building my header tags into the sr variable, however the server received an empty soapenv:Header
This worked for me! (after replacing the SOAP Service URL with a real one and turning off cross-domain restrictions on my browser, as implied by @Prestaul)
I am developing cross-platform app in nativescript for android/ios. I want to use SOAP web services. Please guide me for the same. I used above code for SOAP request & i want SOAP response format, how to handle response. Please review my question - stackoverflow.com/questions/37745840/…
Had to use this recently to support legacy code. Ran across an issue with missing header that was creating a "ContractFilter mismatch at the EndpointDispatcher". Adding xmlhttp.setRequestHeader('SOAPAction', 'http://myurl.com/action'); just before xmlhttp.send(sr) fixed it.
@Rickchip, here is a more general way to solve your problem: Headers can be added by calling setRequestHeader() when needed.
x
xmojmr

There are many quirks in the way browsers handle XMLHttpRequest, this JS code will work across all browsers:
https://github.com/ilinsky/xmlhttprequest

This JS code converts XML into easy to use JavaScript objects:
http://www.terracoder.com/index.php/xml-objectifier

The JS code above can be included in the page to meet your no external library requirement.

var symbol = "MSFT"; 
var xmlhttp = new XMLHttpRequest();
xmlhttp.open("POST", "http://www.webservicex.net/stockquote.asmx?op=GetQuote",true);
xmlhttp.onreadystatechange=function() {
 if (xmlhttp.readyState == 4) {
  alert(xmlhttp.responseText);
  // http://www.terracoder.com convert XML to JSON 
  var json = XMLObjectifier.xmlToJSON(xmlhttp.responseXML);
  var result = json.Body[0].GetQuoteResponse[0].GetQuoteResult[0].Text;
  // Result text is escaped XML string, convert string to XML object then convert to JSON object
  json = XMLObjectifier.xmlToJSON(XMLObjectifier.textToXML(result));
  alert(symbol + ' Stock Quote: $' + json.Stock[0].Last[0].Text); 
 }
}
xmlhttp.setRequestHeader("SOAPAction", "http://www.webserviceX.NET/GetQuote");
xmlhttp.setRequestHeader("Content-Type", "text/xml");
var xml = '<?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> ' +
     '<GetQuote xmlns="http://www.webserviceX.NET/"> ' +
       '<symbol>' + symbol + '</symbol> ' +
     '</GetQuote> ' +
   '</soap:Body> ' +
 '</soap:Envelope>';
xmlhttp.send(xml);
// ...Include Google and Terracoder JS code here...

Two other options:

JavaScript SOAP client: http://www.guru4.net/articoli/javascript-soap-client/en/

Generate JavaScript from a WSDL: https://cwiki.apache.org/confluence/display/CXF20DOC/WSDL+to+Javascript


what should i do if i want to pass multiple envelope ?
i am using the above code ,but xmlhttp.responseText always results as null.can u provide me somelinks to overcome the error
Link for when Google Code gets removed: github.com/ilinsky/xmlhttprequest
P
Prestaul

This cannot be done with straight JavaScript unless the web service is on the same domain as your page. Edit: In 2008 and in IE<10 this cannot be done with straight javascript unless the service is on the same domain as your page.

If the web service is on another domain [and you have to support IE<10] then you will have to use a proxy page on your own domain that will retrieve the results and return them to you. If you do not need old IE support then you need to add CORS support to your service. In either case, you should use something like the lib that timyates suggested because you do not want to have to parse the results yourself.

If the web service is on your own domain then don't use SOAP. There is no good reason to do so. If the web service is on your own domain then modify it so that it can return JSON and save yourself the trouble of dealing with all the hassles that come with SOAP.

Short answer is: Don't make SOAP requests from javascript. Use a web service to request data from another domain, and if you do that then parse the results on the server-side and return them in a js friendly form.


The intention is to have the SOAP server also serve an HTML page for simple test and evaluation. The client would be on the same domain. Not using SOAP for the front end seems to be the accepted view. Any comments as to why? Please add to new question: stackoverflow.com/questions/127038
No point in answering there... I agree with Gizmo on all three points. XML is bloated and a challenge to handle with js while JSON is concise and native.
re "cannot be done": Today it can be done with (mostly) straight JavaScript, if the client supports Cross-Origin Resource Sharing. Hopefully in 3-4 years it will be universally available.
@Constantin, CORS will allow it if you are willing to only support newer browsers and if you have control of the server and can add CORS support there as well. That being said, I still would argue that SOAP calls should only be made between servers and the client should use something more JS friendly like JSON.
-1 as this doesn't answer the question. What about the use case of having a 3rd party application on your domain that you can't "modify to return JSON"?
Y
Yaakov Ellis

You can use the jquery.soap plugin to do the work for you.

This script uses $.ajax to send a SOAPEnvelope. It can take XML DOM, XML string or JSON as input and the response can be returned as either XML DOM, XML string or JSON too.

Example usage from the site:

$.soap({
    url: 'http://my.server.com/soapservices/',
    method: 'helloWorld',

    data: {
        name: 'Remy Blom',
        msg: 'Hi!'
    },

    success: function (soapResponse) {
        // do stuff with soapResponse
        // if you want to have the response as JSON use soapResponse.toJSON();
        // or soapResponse.toString() to get XML string
        // or soapResponse.toXML() to get XML DOM
    },
    error: function (SOAPResponse) {
        // show error
    }
});

g
geekasso

Has anyone tried this? https://github.com/doedje/jquery.soap

Seems very easy to implement.

Example:

$.soap({
url: 'http://my.server.com/soapservices/',
method: 'helloWorld',

data: {
    name: 'Remy Blom',
    msg: 'Hi!'
},

success: function (soapResponse) {
    // do stuff with soapResponse
    // if you want to have the response as JSON use soapResponse.toJSON();
    // or soapResponse.toString() to get XML string
    // or soapResponse.toXML() to get XML DOM
},
error: function (SOAPResponse) {
    // show error
}
});

will result in

<soap:Envelope
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
  <soap:Body>
    <helloWorld>
        <name>Remy Blom</name>
        <msg>Hi!</msg>
    </helloWorld>
  </soap:Body>
</soap:Envelope>

H
Harsha Venkatram

Thomas:

JSON is preferred for front end use because we have easy lookups. Therefore you have no XML to deal with. SOAP is a pain without using a library because of this. Somebody mentioned SOAPClient, which is a good library, we started with it for our project. However it had some limitations and we had to rewrite large chunks of it. It's been released as SOAPjs and supports passing complex objects to the server, and includes some sample proxy code to consume services from other domains.


"JSON is preferred for front end use because it is javascript." - JSON is not JavaScript. (It just looks like JavaScript.)
en.wikipedia.org/wiki/JSON -- Literally stands for "JavaScript Object Notation", and while I agree that JSON is a specification not a language and is therefor decidedly "not javascript" you have to agree that the way it's named could easily confuse folks.
"JSON is preferred for front end use because it is javascript" Please remove this, it is spreading false information: timelessrepo.com/json-isnt-a-javascript-subset
H
Hkachhia
<html>
 <head>
    <title>Calling Web Service from jQuery</title>
    <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.3/jquery.min.js"></script>
    <script type="text/javascript">
        $(document).ready(function () {
            $("#btnCallWebService").click(function (event) {
                var wsUrl = "http://abc.com/services/soap/server1.php";
                var soapRequest ='<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> <getQuote xmlns:impl="http://abc.com/services/soap/server1.php">  <symbol>' + $("#txtName").val() + '</symbol>   </getQuote> </soap:Body></soap:Envelope>';
                               alert(soapRequest)
                $.ajax({
                    type: "POST",
                    url: wsUrl,
                    contentType: "text/xml",
                    dataType: "xml",
                    data: soapRequest,
                    success: processSuccess,
                    error: processError
                });

            });
        });

        function processSuccess(data, status, req) { alert('success');
            if (status == "success")
                $("#response").text($(req.responseXML).find("Result").text());

                alert(req.responseXML);
        }

        function processError(data, status, req) {
        alert('err'+data.state);
            //alert(req.responseText + " " + status);
        } 

    </script>
</head>
<body>
    <h3>
        Calling Web Services with jQuery/AJAX
    </h3>
    Enter your name:
    <input id="txtName" type="text" />
    <input id="btnCallWebService" value="Call web service" type="button" />
    <div id="response" ></div>
</body>
</html>

Hear is best JavaScript with SOAP tutorial with example.

http://www.codeproject.com/Articles/12816/JavaScript-SOAP-Client


S
Shog9

Easily consume SOAP Web services with JavaScript -> Listing B

function fncAddTwoIntegers(a, b)
{
    varoXmlHttp = new XMLHttpRequest();
    oXmlHttp.open("POST",
 "http://localhost/Develop.NET/Home.Develop.WebServices/SimpleService.asmx'",
 false);
    oXmlHttp.setRequestHeader("Content-Type", "text/xml");
    oXmlHttp.setRequestHeader("SOAPAction", "http://tempuri.org/AddTwoIntegers");
    oXmlHttp.send(" \
<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> \
    <AddTwoIntegers xmlns='http://tempuri.org/'> \
      <IntegerOne>" + a + "</IntegerOne> \
      <IntegerTwo>" + b + "</IntegerTwo> \
    </AddTwoIntegers> \
  </soap:Body> \
</soap:Envelope> \
");
    return oXmlHttp.responseXML.selectSingleNode("//AddTwoIntegersResult").text;
}

This may not meet all your requirements but it is a start at actually answering your question. (I switched XMLHttpRequest() for ActiveXObject("MSXML2.XMLHTTP")).


k
kmiklas

Some great examples (and a ready-made JavaScript SOAP client!) here: http://plugins.jquery.com/soap/

Check the readme, and beware the same-origin browser restriction.


Y
Yuci

The question is 'What is the simplest SOAP example using Javascript?'

This answer is of an example in the Node.js environment, rather than a browser. (Let's name the script soap-node.js) And we will use the public SOAP web service from Europe PMC as an example to get the reference list of an article.

const XMLHttpRequest = require("xmlhttprequest").XMLHttpRequest;
const DOMParser = require('xmldom').DOMParser;

function parseXml(text) {
    let parser = new DOMParser();
    let xmlDoc = parser.parseFromString(text, "text/xml");
    Array.from(xmlDoc.getElementsByTagName("reference")).forEach(function (item) {
        console.log('Title: ', item.childNodes[3].childNodes[0].nodeValue);
    });

}

function soapRequest(url, payload) {
    let xmlhttp = new XMLHttpRequest();
    xmlhttp.open('POST', url, true);

    // build SOAP request
    xmlhttp.onreadystatechange = function () {
        if (xmlhttp.readyState == 4) {
            if (xmlhttp.status == 200) {
                parseXml(xmlhttp.responseText);
            }
        }
    }

    // Send the POST request
    xmlhttp.setRequestHeader('Content-Type', 'text/xml');
    xmlhttp.send(payload);
}

soapRequest('https://www.ebi.ac.uk/europepmc/webservices/soap', 
    `<?xml version="1.0" encoding="UTF-8"?>
    <S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
    <S:Header />
    <S:Body>
        <ns4:getReferences xmlns:ns4="http://webservice.cdb.ebi.ac.uk/"
            xmlns:ns2="http://www.scholix.org"
            xmlns:ns3="https://www.europepmc.org/data">
            <id>C7886</id>
            <source>CTX</source>
            <offSet>0</offSet>
            <pageSize>25</pageSize>
            <email>ukpmc-phase3-wp2b---do-not-reply@europepmc.org</email>
        </ns4:getReferences>
    </S:Body>
    </S:Envelope>`);

Before running the code, you need to install two packages:

npm install xmlhttprequest
npm install xmldom

Now you can run the code:

node soap-node.js

And you'll see the output as below:

Title:  Perspective: Sustaining the big-data ecosystem.
Title:  Making proteomics data accessible and reusable: current state of proteomics databases and repositories.
Title:  ProteomeXchange provides globally coordinated proteomics data submission and dissemination.
Title:  Toward effective software solutions for big biology.
Title:  The NIH Big Data to Knowledge (BD2K) initiative.
Title:  Database resources of the National Center for Biotechnology Information.
Title:  Europe PMC: a full-text literature database for the life sciences and platform for innovation.
Title:  Bio-ontologies-fast and furious.
Title:  BioPortal: ontologies and integrated data resources at the click of a mouse.
Title:  PubMed related articles: a probabilistic topic-based model for content similarity.
Title:  High-Impact Articles-Citations, Downloads, and Altmetric Score.

This worked for me, but I personally prefer using axios. let xlms = "<?xml version="1.0" encoding="UTF-8"?> <S:Envelope xmlns:S="schemas.xmlsoap.org/soap/envelope"> <S:Header /> <S:Body> ... </S:Body> </S:Envelope>" axios .post('ebi.ac.uk/europepmc/webservices/soap', xmls, { headers: { 'Content-Type': 'text/xml' } }) .then(res => { console.log(res); }) .catch(err => { console.log(err); });
s
sth

Simplest example would consist of:

Getting user input. Composing XML SOAP message similar to this string POSTing message to webservice url using XHR Parsing webservice's XML SOAP response similar to this

...............
Presenting results to user.

But it's a lot of hassle without external JavaScript libraries.


Not even the first part you didn't answer - Be functional (in other words actually work).
N
Nick
function SoapQuery(){
  var namespace = "http://tempuri.org/";
  var site = "http://server.com/Service.asmx";
  var xmlhttp = new ActiveXObject("Msxml2.ServerXMLHTTP.6.0");
  xmlhttp.setOption(2,  13056 );  /* if use standard proxy */
  var args,fname =  arguments.callee.caller.toString().match(/ ([^\(]+)/)[1]; /*Имя вызвавшей ф-ции*/
  try { args =   arguments.callee.caller.arguments.callee.toString().match(/\(([^\)]+)/)[1].split(",");  
    } catch (e) { args = Array();};
  xmlhttp.open('POST',site,true);  
  var i, ret = "", q = '<?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><'+fname+ ' xmlns="'+namespace+'">';
  for (i=0;i<args.length;i++) q += "<" + args[i] + ">" + arguments.callee.caller.arguments[i] +  "</" + args[i] + ">";
  q +=   '</'+fname+'></soap:Body></soap:Envelope>';
            // Send the POST request
            xmlhttp.setRequestHeader("MessageType","CALL");
            xmlhttp.setRequestHeader("SOAPAction",namespace + fname);
            xmlhttp.setRequestHeader('Content-Type', 'text/xml');
            //WScript.Echo("Запрос XML:" + q);
            xmlhttp.send(q);
     if  (xmlhttp.waitForResponse(5000)) ret = xmlhttp.responseText;
    return ret;
  };





function GetForm(prefix,post_vars){return SoapQuery();};
function SendOrder2(guid,order,fio,phone,mail){return SoapQuery();};

function SendOrder(guid,post_vars){return SoapQuery();};

C
ChokYeeFan

Angularjs $http wrap base on XMLHttpRequest. As long as at the header content set following code will do.

"Content-Type": "text/xml; charset=utf-8"

For example:

function callSoap(){
var url = "http://www.webservicex.com/stockquote.asmx";
var soapXml = "<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:web=\"http://www.webserviceX.NET/\"> "+
         "<soapenv:Header/> "+
         "<soapenv:Body> "+
         "<web:GetQuote> "+
         "<web:symbol></web:symbol> "+
         "</web:GetQuote> "+
         "</soapenv:Body> "+
         "</soapenv:Envelope> ";

    return $http({
          url: url,  
          method: "POST",  
          data: soapXml,  
          headers: {  
              "Content-Type": "text/xml; charset=utf-8"
          }  
      })
      .then(callSoapComplete)
      .catch(function(message){
         return message;
      });

    function callSoapComplete(data, status, headers, config) {
        // Convert to JSON Ojbect from xml
        // var x2js = new X2JS();
        // var str2json = x2js.xml_str2json(data.data);
        // return str2json;
        return data.data;

    }

}