Esempio SOAP più semplice


241

Qual è l'esempio SOAP più semplice usando Javascript?

Per essere il più utile possibile, la risposta dovrebbe:

  • Sii funzionale (in altre parole funziona davvero)
  • Invia almeno un parametro che può essere impostato altrove nel codice
  • Elabora almeno un valore di risultato che può essere letto altrove nel codice
  • Lavora con le versioni più moderne del browser
  • Sii il più chiaro e il più breve possibile, senza utilizzare una libreria esterna

5
Essere semplici e chiari può essere in conflitto con il non utilizzo di una libreria esterna. Vuoi davvero scrivere il tuo convertitore WSDL -> JS class?
mikemaccana,

19
Ho una domanda: se vedessi questa domanda come la prima persona, mi aspetterei che venisse declassato con commenti come "mostra un codice, questo non è" noleggia un programmatore "". Niente di personale, Thomas :) Ma non riesco a capire come la comunità decida cosa sia buono o cattivo.
最 白 目

4
Ehi, non preoccuparti. Immagino che il punto della domanda sia che ci sono molti modi per scrivere un client SOAP usando JavaScript. Molti di loro sono brutti, quindi speravo in alcune idee per mantenerlo pulito.
Thomas Bratt,

@dan è perché 1. questa domanda è piuttosto vecchia, c'erano ancora molte domande fondamentali che venivano poste che per tradizione hanno molti voti, 2. descrive un problema piuttosto semplice, quindi probabilmente tende ad attirare nuovi utenti che potrebbero votare il principio di "hey lo voglio sapere anche io!" invece di "ehi, questa domanda mostra lo sforzo di ricerca. è utile e chiaro!". A mio avviso, poiché la domanda è carente, l'ho sottovalutata. Niente di personale: D
phil294

@ThomasBratt Probabilmente continuerò questo su meta, ma quel tipo di domande merita una possibilità. È la domanda ideale per una biblioteca discendente di riferimento o base di conoscenza. Ma forse la risposta accettata merita anche un incentivo per le gambe extra? Non c'è ancora niente di più accettato di SO, quindi dove altro? Perfino SO ha provato e giocato con l'idea di costruire un sito di documentazione - e ha fallito. Niente da sostituire SO ...
YoYo

Risposte:


201

Questo è il client SOAP JavaScript più semplice che posso creare.

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

2
Che ne dici di inviare un <soapenv: Header>? Ho provato a costruire i miei tag header nella variabile sr, tuttavia il server ha ricevuto un soapenv vuoto: Header
Boiler Bill

Questo ha funzionato per me! (dopo aver sostituito l'URL del servizio SOAP con uno reale e aver disattivato le restrizioni tra domini sul mio browser, come implicito da @Prestaul)
Niko Bellic,

Sto sviluppando un'app multipiattaforma in nativescript per Android / iOS. Voglio usare i servizi web SOAP. Per favore, guidami per lo stesso. Ho usato il codice sopra per la richiesta SOAP e voglio il formato di risposta SOAP, come gestire la risposta. Si prega di rivedere la mia domanda - stackoverflow.com/questions/37745840/…
Onkar Nene,

Ho dovuto usare questo recentemente per supportare il codice legacy. Si è verificato un problema con un'intestazione mancante che stava creando una "mancata corrispondenza di ContractFilter nell'EndpointDispatcher". Aggiunta xmlhttp.setRequestHeader('SOAPAction', 'http://myurl.com/action');appena prima xmlhttp.send(sr)risolto.
RDRick,

80

Esistono molte stranezze nel modo in cui i browser gestiscono XMLHttpRequest, questo codice JS funzionerà su tutti i browser:
https://github.com/ilinsky/xmlhttprequest

Questo codice JS converte XML in oggetti JavaScript facili da usare:
http://www.terracoder.com/index.php/xml-objectifier

Il codice JS sopra può essere incluso nella pagina per soddisfare i requisiti della libreria esterna.

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...

Altre due opzioni:


cosa devo fare se voglio passare più buste?
Ajay Patel,

sto usando il codice sopra, ma xmlhttp.responseText risulta sempre come null.Puoi fornirmi somelink per superare l'errore
user969275

Link per la rimozione di Google Code: github.com/ilinsky/xmlhttprequest
ToastyMallows

48

Questo non può essere fatto con JavaScript semplice a meno che il servizio Web non si trovi nello stesso dominio della tua pagina. Modifica: nel 2008 e in IE <10 questo non può essere fatto con javascript diretto a meno che il servizio non si trovi sullo stesso dominio della tua pagina.

Se il servizio web si trova su un altro dominio [e devi supportare IE <10], dovrai utilizzare una pagina proxy sul tuo dominio che recupererà i risultati e te li restituirà. Se non hai bisogno del vecchio supporto IE, devi aggiungere il supporto CORS al tuo servizio. In entrambi i casi, dovresti usare qualcosa come la lib suggerita da Timyates perché non vuoi analizzare i risultati da solo.

Se il servizio Web si trova nel tuo dominio, non utilizzare SOAP. Non c'è una buona ragione per farlo. Se il servizio Web si trova sul tuo dominio, modificalo in modo che possa restituire JSON e risparmiarti il ​​problema di gestire tutti i problemi associati a SOAP.

La risposta breve è: non effettuare richieste SOAP da JavaScript. Utilizzare un servizio Web per richiedere dati da un altro dominio e, in tal caso, analizzare i risultati sul lato server e restituirli in un formato js amichevole.


1
L'intenzione è che il server SOAP offra anche una pagina HTML per semplici test e valutazioni. Il client si troverebbe sullo stesso dominio. Non usare SOAP per il front-end sembra essere la vista accettata. Qualche commento sul perché? Si prega di aggiungere alla nuova domanda: stackoverflow.com/questions/127038
Thomas Bratt

1
Inutile rispondere lì ... Sono d'accordo con Gizmo su tutti e tre i punti. XML è gonfio e una sfida da gestire con js mentre JSON è conciso e nativo.
Prestaul,

10
ri "impossibile": oggi può essere fatto con JavaScript (principalmente) diretto, se il client supporta la condivisione di risorse tra origini . Spero che tra 3-4 anni sarà universalmente disponibile.
Constantin,

2
@Constantin, CORS lo consentirà se sei disposto a supportare solo i browser più recenti e se hai il controllo del server e puoi aggiungere anche il supporto CORS lì. Detto questo, vorrei ancora sostenere che le chiamate SOAP dovrebbero essere effettuate solo tra server e il client dovrebbe usare qualcosa di più amichevole di JS come JSON.
Prestaul,

1
@NikoBellic potrebbe utilizzare un client basato su browser XMLHttpRequest, probabilmente tramite una libreria come jquery. Un client nodo userebbe qualcos'altro. La maggior parte dei servizi Web utilizza REST come guida per la progettazione delle API, ma esistono molti buoni modelli. La chiave qui è che i corpi di richiesta / risposta sono JSON perché i client javascript (browser / nodo / ovunque) comprendono JSON in modo nativo.
Prestaul,

14

Puoi usare il plugin jquery.soap per fare il lavoro per te.

Questo script utilizza $ .ajax per inviare una busta SOAP. Può accettare XML DOM, stringa XML o JSON come input e la risposta può essere restituita come DOM XML, stringa XML o JSON.

Esempio di utilizzo dal sito:

$.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
    }
});

8

Tommaso:

JSON è preferito per l'uso front-end perché è javascript. Pertanto non hai XML da affrontare. SOAP è un dolore senza usare una libreria per questo. Qualcuno ha menzionato SOAPClient, che è una buona libreria, abbiamo iniziato con esso per il nostro progetto. Tuttavia aveva alcuni limiti e abbiamo dovuto riscriverne grossi pezzi. È stato rilasciato come SOAPjs e supporta il passaggio di oggetti complessi al server e include un codice proxy di esempio per consumare servizi da altri domini.


2
"JSON è preferito per l'uso front-end perché è javascript." - JSON non è JavaScript. (Sembra solo JavaScript.)
nnnnnn

2
en.wikipedia.org/wiki/JSON - Letteralmente significa "JavaScript Object Notation", e mentre sono d'accordo che JSON è una specifica non una lingua e quindi decisamente "non javascript" devi essere d'accordo sul fatto che il suo nome potrebbe confondere facilmente la gente.
P. Roe,

8

Qualcuno ha provato questo? https://github.com/doedje/jquery.soap

Sembra molto facile da implementare.

Esempio:

$.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
}
});

si tradurrà 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>

4
<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 è il miglior JavaScript con l'esercitazione SOAP con l'esempio.

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



3

Utilizza facilmente i servizi Web SOAP con JavaScript -> Elenco 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;
}

Questo potrebbe non soddisfare tutti i tuoi requisiti, ma è un inizio per rispondere effettivamente alla tua domanda. (Ho cambiato XMLHttpRequest () per ActiveXObject ("MSXML2.XMLHTTP") ).


1

L'esempio più semplice sarebbe costituito da:

  1. Ottenere l'input dell'utente.
  2. Comporre un messaggio SOAP XML simile a questo

    <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>
        <GetInfoByZIP xmlns="http://www.webserviceX.NET">
          <USZip>string</USZip>
        </GetInfoByZIP>
      </soap:Body>
    </soap:Envelope>
  3. POST messaggio all'URL del servizio web utilizzando XHR

  4. Analizzare la risposta SOAP XML di webservice in questo modo

    <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
                   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                   xmlns:xsd="http://www.w3.org/2001/XMLSchema">
     <soap:Body>
      <GetInfoByZIPResponse xmlns="http://www.webserviceX.NET">
       <GetInfoByZIPResult>
        <NewDataSet xmlns="">
         <Table>
          <CITY>...</CITY>
          <STATE>...</STATE>
          <ZIP>...</ZIP>
          <AREA_CODE>...</AREA_CODE>
          <TIME_ZONE>...</TIME_ZONE>
         </Table>
        </NewDataSet>
       </GetInfoByZIPResult>
      </GetInfoByZIPResponse>
     </soap:Body>
    </soap:Envelope>
  5. Presentazione dei risultati all'utente.

Ma è una seccatura senza librerie JavaScript esterne.


9
Non un esempio di Javacript.
Thomas Bratt,

Nemmeno la prima parte a cui non hai risposto - Sii funzionale (in altre parole funziona davvero).
Shahar Eldad,

0
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();};

0

Base avvolgente Angularjs $ http su XMLHttpRequest . Fino a quando il contenuto dell'intestazione impostato sarà il seguente codice.

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

Per esempio:

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;

    }

}

0

La domanda è "Qual è l'esempio SOAP più semplice usando Javascript?"

Questa risposta è di un esempio nell'ambiente Node.js , piuttosto che un browser. (Chiamiamo lo script soap-node.js) E useremo il servizio web SOAP pubblico di Europa PMC come esempio per ottenere l'elenco di riferimento di un articolo.

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

Prima di eseguire il codice, è necessario installare due pacchetti:

npm install xmlhttprequest
npm install xmldom

Ora puoi eseguire il codice:

node soap-node.js

E vedrai l'output come di seguito:

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.
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.