El ejemplo de SOAP más simple

241

¿Cuál es el ejemplo SOAP más simple con Javascript?

Para ser lo más útil posible, la respuesta debería:

  • Ser funcional (en otras palabras, realmente funciona)
  • Enviar al menos un parámetro que se pueda establecer en otra parte del código
  • Procese al menos un valor de resultado que pueda leerse en otra parte del código
  • Trabaja con la mayoría de las versiones modernas de navegador
  • Sea lo más claro y breve posible, sin usar una biblioteca externa
Thomas Bratt
fuente
55
Ser simple y claro puede entrar en conflicto con no usar una biblioteca externa. ¿Realmente quieres escribir tu propio conversor de clase WSDL -> JS?
mikemaccana
19
Tengo una pregunta: si vi esta pregunta como la primera persona, esperaría que se rechazara con comentarios como "mostrar algún código, esto no es 'alquilar un codificador'". Nada personal, Thomas :) Pero no puedo entender cómo la comunidad decide qué es bueno y qué es malo.
最 白 目
44
Hola, no te preocupes. Supongo que el punto de la pregunta es que hay muchas formas de escribir un cliente SOAP usando JavaScript. Muchos de ellos son feos, así que esperaba algunas ideas para mantenerlo limpio.
Thomas Bratt
@dan es porque 1. esta pregunta es bastante antigua, todavía había muchas preguntas fundamentales que, según la tradición, tienen muchos votos positivos, 2. describe un problema bastante simple, por lo que probablemente atraiga a nuevos usuarios que puedan votar. el principio de "¡oye, yo también quiero saber eso!" en lugar de "oye, esta pregunta muestra el esfuerzo de investigación. ¡Es útil y claro!". Como la pregunta carece de esto en mi opinión, la rechacé. Nada personal también: D
phil294
@ThomasBratt Probablemente continuaré esto en meta, pero ese tipo de preguntas merecen una oportunidad. Es la pregunta ideal para una biblioteca de referencia de referencia o base de conocimiento. ¿Pero tal vez la respuesta aceptada también merece un incentivo para el trabajo extra? Todavía no hay nada más aceptado que SO, entonces, ¿dónde más? Incluso SO intentó y jugó con la idea de construir un sitio de documentación, y fracasó. Nada reemplaza SO ...
YoYo

Respuestas:

201

Este es el cliente SOAP JavaScript más simple que puedo crear.

<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 -->
stackoverflow128
fuente
2
¿Qué pasa con el envío de un <soapenv: Header>? Intenté construir mis etiquetas de encabezado en la variable sr, sin embargo, el servidor recibió un mensaje vacío: Encabezado
Boiler Bill
¡Esto funcionó para mí! (después de reemplazar la URL del servicio SOAP por una real y desactivar las restricciones entre dominios en mi navegador, según lo implica @Prestaul)
Niko Bellic
Estoy desarrollando una aplicación multiplataforma en nativescript para Android / iOS. Quiero usar los servicios web SOAP. Por favor guíame por lo mismo. Utilicé el código anterior para la solicitud SOAP y quiero el formato de respuesta SOAP, cómo manejar la respuesta. Por favor revise mi pregunta - stackoverflow.com/questions/37745840/…
Onkar Nene
Tuve que usar esto recientemente para admitir código heredado. Se encontró con un problema con la falta de encabezado que estaba creando un "desajuste ContractFilter en el EndpointDispatcher". Agregar xmlhttp.setRequestHeader('SOAPAction', 'http://myurl.com/action');justo antes de xmlhttp.send(sr)arreglarlo.
RDRick
80

Hay muchas peculiaridades en la forma en que los navegadores manejan XMLHttpRequest, este código JS funcionará en todos los navegadores:
https://github.com/ilinsky/xmlhttprequest

Este código JS convierte XML en objetos JavaScript fáciles de usar:
http://www.terracoder.com/index.php/xml-objectifier

El código JS anterior se puede incluir en la página para cumplir con su requisito de biblioteca externa.

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

Otras dos opciones:

Chris Stuart
fuente
¿Qué debo hacer si quiero pasar varios sobres?
Ajay Patel
Estoy usando el código anterior, pero xmlhttp.responseText siempre resulta como nulo. ¿Puede proporcionarme algunos enlaces para superar el error
user969275
Enlace para cuando se elimine Google Code: github.com/ilinsky/xmlhttprequest
ToastyMallows
48

Esto no se puede hacer con JavaScript directo a menos que el servicio web esté en el mismo dominio que su página. Editar: en 2008 y en IE <10, esto no se puede hacer con JavaScript directo a menos que el servicio esté en el mismo dominio que su página.

Si el servicio web está en otro dominio [y debe admitir IE <10], deberá utilizar una página proxy en su propio dominio que recuperará los resultados y se los devolverá. Si no necesita soporte antiguo de IE, entonces necesita agregar soporte CORS a su servicio. En cualquier caso, debe usar algo como la lib que sugiere el tiempo debido a que no desea analizar los resultados usted mismo.

Si el servicio web está en su propio dominio, no use SOAP. No hay una buena razón para hacerlo. Si el servicio web está en su propio dominio, modifíquelo para que pueda devolver JSON y ahorrarse la molestia de lidiar con todas las molestias que vienen con SOAP.

La respuesta corta es: No haga solicitudes SOAP desde javascript. Utilice un servicio web para solicitar datos de otro dominio, y si lo hace, analice los resultados en el lado del servidor y devuélvalos en un formato amigable js.

Prestaul
fuente
1
La intención es que el servidor SOAP también sirva una página HTML para pruebas y evaluaciones simples. El cliente estaría en el mismo dominio. No usar SOAP para el front-end parece ser la vista aceptada. ¿Algún comentario sobre por qué? Agregue a la nueva pregunta: stackoverflow.com/questions/127038
Thomas Bratt el
1
No tiene sentido responder allí ... Estoy de acuerdo con Gizmo en los tres puntos. XML está hinchado y es un desafío manejarlo con js mientras que JSON es conciso y nativo.
Prestaul
10
re "no se puede hacer": hoy se puede hacer con (en su mayoría) JavaScript directo, si el cliente admite el uso compartido de recursos de origen cruzado . Esperemos que en 3-4 años esté universalmente disponible.
Constantin
2
@Constantin, CORS lo permitirá si está dispuesto a admitir solo navegadores más nuevos y si tiene el control del servidor y también puede agregar soporte de CORS allí. Dicho esto, todavía argumentaría que las llamadas SOAP solo deben hacerse entre servidores y el cliente debe usar algo más amigable con JS como JSON.
Prestaul
1
@NikoBellic podría usar un cliente basado en navegador XMLHttpRequest, probablemente a través de una biblioteca como jquery. Un cliente de nodo usaría otra cosa. La mayoría de los servicios web usan REST como guía para diseñar su API, pero hay muchos patrones buenos. La clave aquí es que los cuerpos de solicitud / respuesta son JSON porque los clientes javascript (navegador / nodo / donde sea) entienden JSON de forma nativa.
Prestaul
14

Puede usar el complemento jquery.soap para hacer el trabajo por usted.

Este script usa $ .ajax para enviar un SOAPEnvelope. Puede tomar XML DOM, cadena XML o JSON como entrada y la respuesta puede devolverse como XML DOM, cadena XML o JSON también.

Ejemplo de uso del sitio:

$.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
    }
});
Yaakov Ellis
fuente
8

Thomas

Se prefiere JSON para el uso frontal porque es javascript. Por lo tanto, no tiene XML para tratar. SOAP es un dolor sin usar una biblioteca debido a esto. Alguien mencionó SOAPClient, que es una buena biblioteca, comenzamos con ella para nuestro proyecto. Sin embargo, tenía algunas limitaciones y tuvimos que reescribir grandes partes de él. Se lanzó como SOAPjs y admite el paso de objetos complejos al servidor, e incluye algunos códigos proxy de muestra para consumir servicios de otros dominios.

Richard June
fuente
2
"Se prefiere JSON para uso frontal porque es javascript". - JSON no es JavaScript. (Simplemente parece JavaScript.)
nnnnnn
2
en.wikipedia.org/wiki/JSON - Literalmente significa "JavaScript Object Notation", y aunque estoy de acuerdo en que JSON es una especificación, no un lenguaje y, por lo tanto, definitivamente "no es JavaScript", debe aceptar que la forma en que se nombra podría confundir fácilmente a la gente.
P. Roe
8

¿Alguien ha probado esto? https://github.com/doedje/jquery.soap

Parece muy fácil de implementar.

Ejemplo:

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

resultará en

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

Escuchar es el mejor tutorial de JavaScript con SOAP con ejemplo.

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

Hkachhia
fuente
3

Algunos buenos ejemplos (¡y un cliente SOAP JavaScript listo!) Aquí: http://plugins.jquery.com/soap/

Verifique el archivo Léame y tenga cuidado con la restricción del navegador del mismo origen.

kmiklas
fuente
3

Consuma fácilmente los servicios web SOAP con JavaScript -> Listado 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;
}

Es posible que esto no cumpla con todos sus requisitos, pero es un comienzo para responder su pregunta. ( Cambié XMLHttpRequest () por ActiveXObject ("MSXML2.XMLHTTP") ).

usuario423430
fuente
1

El ejemplo más simple consistiría en:

  1. Obteniendo la entrada del usuario.
  2. Redactar un mensaje XML SOAP similar a este

    <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. PUBLICANDO un mensaje en la URL del servicio web usando XHR

  4. Analizando la respuesta SOAP XML del servicio web similar a esta

    <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. Presentación de resultados al usuario.

Pero es una gran molestia sin bibliotecas externas de JavaScript.

Constantin
fuente
99
No es un ejemplo de Javacript.
Thomas Bratt
Ni siquiera la primera parte que no respondiste: sé funcional (en otras palabras, realmente funciona).
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();};
Mella
fuente
0

Angularjs $ http wrap base en XMLHttpRequest . Siempre y cuando se establezca el contenido del encabezado, lo hará el siguiente código.

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

Por ejemplo:

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;

    }

}
ChokYeeFan
fuente
0

La pregunta es '¿Cuál es el ejemplo SOAP más simple que usa Javascript?'

Esta respuesta es de un ejemplo en el entorno Node.js , en lugar de un navegador. (Pongamos el nombre del script soap-node.js) Y utilizaremos el servicio web público SOAP de Europe PMC como ejemplo para obtener la lista de referencias de un artículo.

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

Antes de ejecutar el código, debe instalar dos paquetes:

npm install xmlhttprequest
npm install xmldom

Ahora puedes ejecutar el código:

node soap-node.js

Y verá la salida de la siguiente manera:

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