Простейший пример SOAP
Какой простейший пример SOAP с использованием Javascript?
Чтобы быть максимально полезным, ответ должен:
- Быть функциональным (другими словами, фактически работать)
- Отправьте хотя бы один параметр, который можно установить в другом месте кода
- Обработайте хотя бы одно значение результата, которое можно прочитать в другом месте кода
- Работа с большинством современных версий браузера
- Будьте максимально понятны и коротки, не используя внешнюю библиотеку.
13 ответов
Это самый простой 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('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 -->
В способе обработки браузерами 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...
Два других варианта:
Клиент JavaScript SOAP:
http://www.guru4.net/articoli/javascript-soap-client/en/Генерация JavaScript из WSDL:
https://cwiki.apache.org/confluence/display/CXF20DOC/WSDL+to+Javascript
Это невозможно сделать с помощью простого JavaScript, если веб-служба не находится в том же домене, что и ваша страница. Изменить: в 2008 году и в IE<10 это не может быть сделано с помощью простого JavaScript, если служба находится в том же домене, что и ваша страница.
Если веб-служба находится в другом домене [и вам необходимо поддерживать IE<10], вам придется использовать прокси-страницу в своем собственном домене, которая будет получать результаты и возвращать их вам. Если вам не нужна старая поддержка IE, вам нужно добавить поддержку CORS к вашему сервису. В любом случае, вы должны использовать что-то вроде библиотеки, которую предложил Timyates, потому что вы не хотите анализировать результаты самостоятельно.
Если веб-служба находится в вашем собственном домене, не используйте SOAP. Нет веских причин для этого. Если веб-сервис находится в вашем собственном домене, измените его так, чтобы он мог возвращать JSON и избавлял вас от необходимости справляться со всеми трудностями, которые идут с SOAP.
Краткий ответ: не делайте SOAP-запросов из javascript. Используйте веб-сервис для запроса данных из другого домена, и если вы это сделаете, то проанализируйте результаты на стороне сервера и верните их в удобной для js форме.
Вы можете использовать плагин 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
}
});
Кто-нибудь пробовал это? 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>
Томас:
JSON предпочтительнее для использования на переднем конце, потому что это javascript. Поэтому у вас нет XML для работы. SOAP это боль без использования библиотеки из-за этого. Кто-то упомянул SOAPClient, которая является хорошей библиотекой, мы начали с нее для нашего проекта. Однако у этого были некоторые ограничения, и мы должны были переписать его большими кусками. Он выпущен как SOAPjs и поддерживает передачу сложных объектов на сервер, а также включает в себя некоторый пример прокси-кода для использования служб из других доменов.
<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
Легко использовать SOAP Web-сервисы с помощью 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")).
Несколько отличных примеров (и готовый клиент JavaScript SOAP!) Здесь: http://plugins.jquery.com/soap/
Проверьте файл readme и остерегайтесь ограничений браузера того же источника.
Вопрос "Какой простейший пример SOAP с использованием Javascript?"
Этот ответ является примером в среде Node.js, а не в браузере. (Давайте назовем скрипт soap-node.js) И мы будем использовать общедоступный веб-сервис SOAP из Европы 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.
Простейший пример состоит из:
- Получение пользовательского ввода.
Составление сообщения 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>
Размещение сообщения на URL веб-сервиса с использованием XHR
Синтаксический анализ ответа 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>
Представление результатов пользователю.
Но это много хлопот без внешних библиотек JavaScript.
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();};
База данных 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;
}
}