如何使用Javascript编写最简单的SOAP示例?
为了尽可能有用,答案应该:
- 具有功能性(也就是实际上能工作)
- 发送至少一个参数,可以在代码中的其他位置设置
- 处理至少一个结果值,可以在代码的其他位置读取
- 与大多数现代浏览器版本兼容
- 尽可能清晰简短,不使用外部库
如何使用Javascript编写最简单的SOAP示例?
为了尽可能有用,答案应该:
这是我能够创建的最简单的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 -->
xmlhttp.send(sr)
之前添加 xmlhttp.setRequestHeader('SOAPAction', 'http://myurl.com/action');
就解决了该问题。 - Rickchip浏览器处理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/
从WSDL生成JavaScript:
https://cwiki.apache.org/confluence/display/CXF20DOC/WSDL+to+Javascript
除非网络服务与您的页面在同一域中,否则无法使用纯JavaScript完成此操作。 在2008年和IE<10中,如果服务不在与您的页面相同的域中,则无法使用纯javascript完成此操作。
如果网络服务位于另一个域中[并且您需要支持IE<10],则必须在自己的域上使用代理页面来检索结果并将其返回给您。 如果您不需要旧版IE的支持,则需要为服务添加CORS支持。 无论哪种情况,您都应该使用像timyates建议的库,因为您不希望自己解析结果。
如果网络服务位于您自己的域上,请不要使用SOAP。 没有充分的理由这样做。 如果网络服务在您自己的域上,请修改它以便能够返回JSON,并避免处理所有与SOAP相关的麻烦。
简短的答案是:不要从javascript发出SOAP请求。 使用网络服务从另一个域请求数据,如果这样做,则在服务器端解析结果并以js友好的形式返回它们。
XMLHttpRequest
,通常是通过像jquery这样的库。而Node客户端则会使用其他东西。大多数Web服务都使用REST作为设计其API的指南,但也有许多好的模式。关键在于请求/响应体是JSON,因为JavaScript客户端(浏览器/Node/任何地方)本地理解JSON。 - Prestaul您可以使用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>
Thomas:
JSON 更适用于前端使用,因为我们可以轻松查找。因此您无需处理 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 Web服务 -> 清单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/
请查看自述文件,并注意同源浏览器限制。
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.