Exemple SOAP le plus simple


241

Quel est l'exemple SOAP le plus simple utilisant Javascript?

Pour être aussi utile que possible, la réponse doit:

  • Être fonctionnel (en d'autres termes, fonctionner réellement)
  • Envoyer au moins un paramètre qui peut être défini ailleurs dans le code
  • Traiter au moins une valeur de résultat qui peut être lue ailleurs dans le code
  • Fonctionne avec la plupart des versions de navigateur modernes
  • Soyez aussi clair et court que possible, sans utiliser de bibliothèque externe

5
Être simple et clair peut entrer en conflit avec le fait de ne pas utiliser de bibliothèque externe. Voulez-vous vraiment écrire votre propre convertisseur de classe WSDL -> JS?
mikemaccana

19
J'ai une question: si je voyais cette question comme la première personne, je m'attendrais à ce qu'elle soit sous-votée avec des commentaires comme "montrer du code, ce n'est pas" louer un codeur "". Rien de personnel, Thomas :) Mais je ne peux pas comprendre comment la communauté décide ce qui est bon ou mauvais.
最 白 目

4
Hé pas de soucis. Je suppose que le point de la question est qu'il existe de nombreuses façons d'écrire un client SOAP en utilisant JavaScript. Beaucoup d'entre eux sont moches, alors j'espérais avoir des idées pour le garder propre.
Thomas Bratt

@dan c'est parce que 1. cette question est assez ancienne, il y avait encore beaucoup de questions fondamentales posées qui, par tradition, ont beaucoup de votes positifs, 2. elle décrit un problème assez simple, donc elle a probablement tendance à attirer de nouveaux utilisateurs qui pourraient voter par le principe du "hé je veux le savoir aussi!" au lieu de "hé, cette question montre l'effort de recherche. c'est utile et clair!". Comme la question manque à mon avis, je l'ai rejetée. Rien de personnel aussi: D
phil294

@ThomasBratt Je vais probablement continuer sur meta, mais ce type de questions mérite une chance. C'est la question idéale pour une bibliothèque d'ascendance de référence ou de base de connaissances. Mais peut-être que la réponse acceptée mérite également une incitation pour le travail supplémentaire? Il n'y a toujours rien de plus accepté que SO, alors où d'autre? Même SO a essayé et joué avec l'idée de construire un site de documentation - et a échoué. Rien pour remplacer SO ...
YoYo

Réponses:


201

Il s'agit du client SOAP JavaScript le plus simple que je puisse créer.

<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
Qu'en est-il de l'envoi d'un <soapenv: Header>? J'ai essayé de construire mes balises d'en-tête dans la variable sr, mais le serveur a reçu un soapenv vide: Header
Boiler Bill

Cela a fonctionné pour moi! (après avoir remplacé l'URL du service SOAP par une URL réelle et désactivé les restrictions interdomaines sur mon navigateur, comme l'indique @Prestaul)
Niko Bellic

Je développe une application multiplateforme en nativescript pour android / ios. Je souhaite utiliser les services Web SOAP. Veuillez me guider pour la même chose. J'ai utilisé le code ci-dessus pour la demande SOAP et je veux un format de réponse SOAP, comment gérer la réponse. Veuillez revoir ma question - stackoverflow.com/questions/37745840/…
Onkar Nene

J'ai dû l'utiliser récemment pour prendre en charge le code hérité. A traversé un problème avec un en-tête manquant qui créait une "non-concordance de ContractFilter sur EndpointDispatcher". L'ajout xmlhttp.setRequestHeader('SOAPAction', 'http://myurl.com/action');juste avant l'a xmlhttp.send(sr)corrigé.
RDRick

80

Il existe de nombreuses bizarreries dans la façon dont les navigateurs gèrent XMLHttpRequest, ce code JS fonctionnera sur tous les navigateurs:
https://github.com/ilinsky/xmlhttprequest

Ce code JS convertit XML en objets JavaScript faciles à utiliser:
http://www.terracoder.com/index.php/xml-objectifier

Le code JS ci-dessus peut être inclus dans la page pour répondre à vos besoins sans bibliothèque externe.

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

Deux autres options:


que dois-je faire si je souhaite passer plusieurs enveloppes?
Ajay Patel

j'utilise le code ci-dessus, mais xmlhttp.responseText se traduit toujours par null.can u me fournit des liens pour surmonter l'erreur
user969275

Lien pour la suppression de Google Code: github.com/ilinsky/xmlhttprequest
ToastyMallows

48

Cela ne peut pas être fait avec du JavaScript simple, sauf si le service Web est sur le même domaine que votre page. Edit: en 2008 et dans IE <10, cela ne peut pas être fait avec du javascript simple, sauf si le service est sur le même domaine que votre page.

Si le service Web se trouve sur un autre domaine [et que vous devez prendre en charge IE <10], vous devrez utiliser une page proxy sur votre propre domaine qui récupérera les résultats et vous les renverra. Si vous n'avez pas besoin de l'ancien support IE, vous devez ajouter le support CORS à votre service. Dans les deux cas, vous devez utiliser quelque chose comme la bibliothèque suggérée par timyates, car vous ne voulez pas avoir à analyser les résultats vous-même.

Si le service Web est sur votre propre domaine, n'utilisez pas SOAP. Il n'y a aucune bonne raison de le faire. Si le service Web est sur votre propre domaine, modifiez-le afin qu'il puisse renvoyer JSON et évitez de vous occuper de tous les tracas qui accompagnent SOAP.

La réponse courte est: ne faites pas de demandes SOAP à partir de javascript. Utilisez un service Web pour demander des données à un autre domaine, et si vous le faites, analysez les résultats côté serveur et renvoyez-les sous une forme conviviale js.


1
L'intention est que le serveur SOAP serve également une page HTML pour un test et une évaluation simples. Le client serait sur le même domaine. Ne pas utiliser SOAP pour le frontal semble être la vue acceptée. Des commentaires sur pourquoi? Veuillez ajouter à une nouvelle question: stackoverflow.com/questions/127038
Thomas Bratt

1
Inutile d'y répondre ... Je suis d'accord avec Gizmo sur les trois points. XML est gonflé et un défi à gérer avec js tandis que JSON est concis et natif.
Prestaul

10
re "ne peut pas être fait": Aujourd'hui, cela peut être fait avec (principalement) du JavaScript simple, si le client prend en charge le partage de ressources d'origine croisée . Espérons que dans 3 à 4 ans, il sera universellement disponible.
Constantin

2
@Constantin, CORS l'autorisera si vous souhaitez uniquement prendre en charge les nouveaux navigateurs et si vous avez le contrôle du serveur et pouvez y ajouter également la prise en charge CORS. Cela étant dit, je dirais toujours que les appels SOAP ne devraient être effectués qu'entre serveurs et que le client devrait utiliser quelque chose de plus convivial JS comme JSON.
Prestaul

1
@NikoBellic qu'un client basé sur un navigateur peut utiliser XMLHttpRequest, probablement via une bibliothèque telle que jquery. Un client de noeud utiliserait autre chose. La plupart des services Web utilisent REST comme guide pour concevoir leur API, mais il existe de nombreux bons modèles. La clé ici est que les corps de demande / réponse sont JSON parce que les clients javascript (navigateur / nœud / partout) comprennent JSON nativement.
Prestaul

14

Vous pouvez utiliser le plugin jquery.soap pour faire le travail à votre place.

Ce script utilise $ .ajax pour envoyer une enveloppe SOAPEnvelope. Il peut prendre XML DOM, chaîne XML ou JSON en entrée et la réponse peut être renvoyée aussi bien en XML DOM, chaîne XML ou JSON.

Exemple d'utilisation du 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
    }
});

8

Thomas:

JSON est préféré pour une utilisation frontale car il est en javascript. Vous n'avez donc pas de XML à gérer. SOAP est une douleur sans utiliser une bibliothèque à cause de cela. Quelqu'un a mentionné SOAPClient, qui est une bonne bibliothèque, nous l'avons commencé pour notre projet. Cependant, il avait certaines limites et nous avons dû en réécrire de gros morceaux. Il a été publié en tant que SOAPjs et prend en charge le passage d'objets complexes au serveur, et comprend des exemples de code proxy pour consommer les services d'autres domaines.


2
"JSON est préféré pour une utilisation frontale car il est javascript." - JSON n'est pas JavaScript. (Cela ressemble à JavaScript.)
nnnnnn

2
en.wikipedia.org/wiki/JSON - Littéralement signifie "JavaScript Object Notation", et bien que je convienne que JSON est une spécification pas un langage et est donc décidément "pas javascript", vous devez convenir que la façon dont il est nommé pourrait confondre facilement les gens.
P. Roe

8

Quelqu'un at-il essayé cela? https://github.com/doedje/jquery.soap

Semble très facile à mettre en œuvre.

Exemple:

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

aura pour résultat

<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 is best JavaScript with SOAP tutorial with example.

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



3

Consommer facilement des services Web SOAP avec 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;
}

Cela peut ne pas répondre à toutes vos exigences, mais c'est un début pour répondre à votre question. (J'ai changé XMLHttpRequest () pour ActiveXObject ("MSXML2.XMLHTTP") ).


1

L'exemple le plus simple consisterait en:

  1. Obtenir la contribution de l'utilisateur.
  2. Composer un message XML SOAP similaire à celui-ci

    <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. POSTAGE d'un message à l'URL du service Web à l'aide de XHR

  4. Analyser la réponse SOAP XML de webservice similaire à ceci

    <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. Présentation des résultats à l'utilisateur.

Mais c'est beaucoup de tracas sans bibliothèques JavaScript externes.


9
Pas un exemple Javacript.
Thomas Bratt,

Pas même la première partie à laquelle vous n'avez pas répondu - Soyez fonctionnel (en d'autres termes, travaillez réellement).
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

Angularjs $ http wrap base sur XMLHttpRequest . Tant que dans le contenu de l'en-tête, le code suivant fera l'affaire.

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

Par exemple:

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 question est «Quel est l'exemple SOAP le plus simple utilisant Javascript?

Cette réponse est un exemple dans l' environnement Node.js , plutôt qu'un navigateur. (Appelons le script soap-node.js) Et nous utiliserons le service Web public SOAP d'Europe PMC comme exemple pour obtenir la liste de référence d'un 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>`);

Avant d'exécuter le code, vous devez installer deux packages:

npm install xmlhttprequest
npm install xmldom

Vous pouvez maintenant exécuter le code:

node soap-node.js

Et vous verrez la sortie comme ci-dessous:

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.
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.