Найпростіший приклад SOAP


241

Який найпростіший приклад SOAP за допомогою Javascript?

Щоб бути максимально корисною, відповідь повинна:

  • Будьте функціональними (іншими словами фактично працюйте)
  • Надішліть принаймні один параметр, який можна встановити в іншому місці коду
  • Обробіть принаймні одне значення результату, яке можна прочитати в іншому місці коду
  • Працюйте з більшістю сучасних версій браузера
  • Будьте максимально чіткими та короткими, не використовуючи зовнішню бібліотеку

5
Бути простою і зрозумілою може конфліктувати з не використанням зовнішньої бібліотеки. Ви дійсно хочете написати власний перетворювач класів WSDL -> JS?
mikemaccana

19
У мене виникає питання: якщо я бачив це питання як першу людину, я б очікував, що його буде оскаржено коментарями на кшталт "показати якийсь код, це не" орендувати кодер "". Нічого особистого, Томас :) Але я не можу зрозуміти, як громада вирішує, що добре, а що погано.
最 白 目

4
Гей, не хвилюйся. Я думаю, що питання полягає в тому, що існує багато способів написання клієнта SOAP за допомогою JavaScript. Багато з них некрасиві, тому я сподівався на деякі ідеї щодо збереження його в чистоті.
Томас Братт

@dan це тому, що 1. це питання досить старе, все ще було багато принципових питань, які задаються, які за традицією мають багато підсумків, 2. він описує досить просту проблему, тому, ймовірно, має тенденцію залучати нових користувачів, які можуть проголосувати принцип "ей, я теж хочу це знати!" замість "ей, це питання показує зусилля в дослідженні. Це корисно і зрозуміло!". Оскільки цього питання на мій погляд не вистачає, я спростував це. Нічого особистого теж: D
phil294

@ThomasBratt Я, мабуть, продовжую це на мета, але такі питання питань заслуговують на шанс. Це ідеальне питання для бібліотеки посилань або бази знань. Але просто, можливо, прийнята відповідь також заслуговує на стимул для додаткової роботи? Все ще немає нічого більш прийнятого, ніж ТА, і де ще? Навіть ТАК намагався зіграти з ідеєю побудови сайту документації - і не вдався. Ніщо не замінить ТАК ...
YoYo

Відповіді:


201

Це найпростіший клієнт JavaScript SOAP, який я можу створити.

<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
Що щодо надсилання <soapenv: Header>? Я спробував побудувати свої теги заголовка в змінну sr, однак сервер отримав порожнє soapenv: Header
Boiler Bill

Це працювало для мене! (після заміни URL-адреси служби SOAP справжньою та відключення міждоменних обмежень на моєму браузері, як це передбачає @Prestaul)
Niko Bellic

Я розробляю крос-платформенний додаток у Nativecript для android / ios. Я хочу використовувати веб-сервіси SOAP. Будь ласка, направляйте мене на те саме. Я використовував вище код для запиту SOAP & я хочу формат відповіді SOAP, як обробляти відповідь. Перегляньте моє запитання - stackoverflow.com/questions/37745840/…
Onkar Nene

Довелося використовувати це нещодавно для підтримки застарілого коду. Натрапив на проблему з відсутнім заголовком, який створював "Невідповідність ContractFilter у EndpointDispatcher". Додавання xmlhttp.setRequestHeader('SOAPAction', 'http://myurl.com/action');безпосередньо перед xmlhttp.send(sr)виправленням.
RDRick

80

Існує багато химерностей у тому, як браузери обробляють XMLHttpRequest, цей JS-код буде працювати у всіх браузерах:
https://github.com/ilinsky/xmlhttprequest

Цей JS-код перетворює XML у прості у використанні об’єкти JavaScript:
http://www.terracoder.com/index.php/xml-objectifier

Код JS, наведений вище, може бути включений на сторінку, щоб відповідати вашим вимогам без зовнішньої бібліотеки.

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

Ще два варіанти:


що мені робити, якщо я хочу передати кілька конвертів?
Аджай Патель

Я використовую вищевказаний код, але xmlhttp.responseText завжди призводить до того, що null.can u надає мені додаткові посилання для подолання помилки
user969275

Посилання на те, коли видаляється код Google: github.com/ilinsky/xmlhttprequest
ToastyMallows

48

Це неможливо зробити за допомогою прямого JavaScript, якщо веб-служба не знаходиться на тому ж домені, що і ваша сторінка. Редагувати: У 2008 році та в IE <10 це неможливо зробити за допомогою прямого javascript, якщо служба не знаходиться в тому ж домені, що і ваша сторінка.

Якщо веб-служба знаходиться на іншому домені [і вам потрібно підтримувати IE <10], вам доведеться використовувати сторінку проксі у власному домені, яка отримає результати та поверне їх вам. Якщо вам не потрібна стара підтримка IE, вам потрібно додати підтримку CORS до ваших послуг. В будь-якому випадку вам слід скористатися чимось на зразок вкладки, яку запропонували тімейти, тому що вам не хочеться самостійно аналізувати результати.

Якщо веб-служба знаходиться у вашому власному домені, тоді не використовуйте SOAP. Немає вагомих причин для цього. Якщо веб-сервіс знаходиться у вашому власному домені, то змініть його так, щоб він міг повернути JSON і заощадити собі проблеми зі всіма клопотами, які виникають із SOAP.

Коротка відповідь: Не робіть запити SOAP з JavaScript. Використовуйте веб-сервіс для запиту даних з іншого домену, а якщо ви це зробите, тоді проаналізуйте результати на стороні сервера та поверніть їх у зручній для js формі.


1
Наміром є сервер SOAP також обслуговувати HTML-сторінку для простого тестування та оцінки. Клієнт був би в одному домені. Невикористання SOAP для переднього кінця здається прийнятим. Будь-які коментарі, чому? Будь ласка, додайте до нового питання: stackoverflow.com/questions/127038
Thomas Bratt

1
Немає сенсу відповідати там ... Я погоджуюся з Gizmo по всіх трьох пунктах. XML роздутий, і проблема з js, коли JSON є лаконічним та рідним.
Prestaul

10
повторно "неможливо зробити": сьогодні це можна зробити за допомогою (в основному) прямого JavaScript, якщо клієнт підтримує перехресне походження ресурсів . Сподіваємось, через 3-4 роки він буде доступний повсюдно.
Константин

2
@Constantin, CORS дозволить це, якщо ви готові підтримувати лише новіші браузери та якщо у вас є контроль над сервером і ви можете також додати підтримку CORS. Зважаючи на це, я все ще стверджую, що дзвінки SOAP повинні здійснюватися лише між серверами, а клієнт повинен використовувати щось більш дружнє для JS, як JSON.
Prestaul

1
@NikoBellic клієнт на базі браузера може використовувати XMLHttpRequest, ймовірно, через бібліотеку, таку як jquery. Клієнт вузла використовував би щось інше. Більшість веб-сервісів використовують REST як посібник для розробки своїх програм, але є багато хороших зразків. Ключовим тут є те, що органи запиту / відповіді - JSON, тому що клієнти javascript (браузер / вузол / де завгодно) розуміють JSON спочатку.
Prestaul

14

Ви можете використовувати плагін jquery.soap, щоб зробити роботу за вас.

Цей сценарій використовує $ .ajax для надсилання SOAPEnvelope. Це може приймати XML DOM, XML рядок або JSON як вхід, і відповідь може бути повернуто як XML DOM, XML рядок або JSON.

Приклад використання з сайту:

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

Томас:

JSON є кращим для переднього використання, оскільки це JavaScript. Тому у вас немає XML для вирішення. SOAP - це біль без використання бібліотеки через це. Хтось згадав SOAPClient, що є гарною бібліотекою, ми почали з цього наш проект. Однак це мало деякі обмеження, і нам довелося переписати великі куски. Він випущений як SOAPjs і підтримує передачу складних об'єктів серверу і включає деякий зразок проксі-коду для споживання послуг з інших доменів.


2
"JSON є кращим для використання на передньому кінці, оскільки це javascript." - JSON - це не JavaScript. (Це просто схоже на JavaScript.)
nnnnnn

2
en.wikipedia.org/wiki/JSON - Буквально означає «Нотація об’єкта JavaScript», і, хоча я погоджуюся, що JSON є специфікацією, а не мовою, і тому рішуче «не javascript», ви повинні погодитися, що спосіб її імені міг би бути легко сплутати людей.
P. Roe

8

Хтось пробував це? https://github.com/doedje/jquery.soap

Здається, дуже легко здійснити.

Приклад:

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

призведе до

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

Слухайте найкраще JavaScript з підручником SOAP з прикладом.

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


3

Деякі чудові приклади (і готовий клієнт JavaScript SOAP!) Тут: http://plugins.jquery.com/soap/

Перевірте readme та остерігайтеся обмеження веб-переглядача того самого походження.


3

Легко споживати веб-сервіси SOAP за допомогою JavaScript -> Лістинг 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;
}

Це може не відповідати всім вашим вимогам, але це справді відповідь на ваше запитання. (Я переключив XMLHttpRequest () для ActiveXObject ("MSXML2.XMLHTTP") ).


1

Найпростіший приклад складається з:

  1. Отримання вводу користувача.
  2. Складання повідомлення XML SOAP, подібне до цього

    <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. POSTing message to urlservice url using XHR

  4. Розбір відповіді XML SOAP веб-сервісу аналогічний цьому

    <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. Представлення результатів користувачеві.

Але без зовнішніх бібліотек JavaScript багато клопоту.


9
Не приклад Javacript.
Томас Братт

Навіть перша частина, на яку ви не відповіли - Будьте функціональні (іншими словами насправді працюють).
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 оберніть базу на XMLHttpRequest . До тих пір, поки набір вмісту заголовка буде робити наступний код.

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

Наприклад:

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

Питання "Який найпростіший приклад SOAP за допомогою Javascript?"

Ця відповідь є прикладом у середовищі Node.js , а не в браузері. (Назвемо скрипт soap-node.js) І ми використаємо загальнодоступний веб-сервіс SOAP від ​​Europe PMC як приклад, щоб отримати довідковий список статті.

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

Перш ніж запустити код, потрібно встановити два пакети:

npm install xmlhttprequest
npm install xmldom

Тепер ви можете запустити код:

node soap-node.js

І ви побачите результат, як показано нижче:

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.
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.