Node.js:如何使用 SOAP XML Web 服务
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/8655252/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Node.js: how to consume SOAP XML web service
提问by WHITECOLOR
I wonder what is the best way to consume SOAP XML web service with node.js
我想知道使用 node.js 使用 SOAP XML Web 服务的最佳方式是什么
Thanks!
谢谢!
采纳答案by Juicy Scripter
回答by tmanolatos
I think that an alternative would be to:
我认为另一种选择是:
- use a tool such as SoapUI (http://www.soapui.org) to record input and output xml messages
- use node request (https://github.com/mikeal/request) to form input xml message to send (POST) the request to the web service (note that standard javascript templating mechanisms such as ejs (http://embeddedjs.com/) or mustache (https://github.com/janl/mustache.js) could help you here) and finally
- use an XML parser to deserialize response data to JavaScript objects
- 使用诸如 SoapUI ( http://www.soapui.org) 之类的工具来记录输入和输出 xml 消息
- 使用节点请求 ( https://github.com/mikeal/request) 形成输入 xml 消息以将请求发送 (POST) 到 Web 服务(注意标准的 javascript 模板机制,例如 ejs ( http://embeddedjs.com /) 或小胡子 ( https://github.com/janl/mustache.js) 可以在这里帮助你) 最后
- 使用 XML 解析器将响应数据反序列化为 JavaScript 对象
Yes, this is a rather dirty and low level approach but it should work without problems
是的,这是一种相当肮脏和低级的方法,但它应该可以正常工作
回答by jtlindsey
If node-soapdoesn't work for you, just use noderequestmodule and then convert the xml to json if needed.
如果node-soap不适合您,只需使用noderequest模块,然后根据需要将 xml 转换为 json。
My request wasn't working with node-soapand there is no support for that module beyond the paid support, which was beyond my resources. So i did the following:
我的请求不起作用,node-soap除了付费支持之外,没有对该模块的支持,这超出了我的资源范围。所以我做了以下事情:
- downloaded SoapUIon my Linux machine.
- copied the WSDL xml to a local file
curl http://192.168.0.28:10005/MainService/WindowsService?wsdl > wsdl_file.xml - In SoapUI I went to
File > New Soap projectand uploaded mywsdl_file.xml. - In the navigator i expanded one of the services and right clicked
the request and clicked on
Show Request Editor.
- 在我的 Linux 机器上下载了SoapUI。
- 将 WSDL xml 复制到本地文件
curl http://192.168.0.28:10005/MainService/WindowsService?wsdl > wsdl_file.xml - 在 SoapUI 中,我去
File > New Soap project上传了我的wsdl_file.xml. - 在导航器中,我展开了一项服务并右键单击请求并单击
Show Request Editor。
From there I could send a request and make sure it worked and I could also use the Rawor HTMLdata to help me build an external request.
从那里我可以发送请求并确保它有效,我也可以使用Raw或HTML数据来帮助我构建外部请求。
Raw from SoapUI for my request
来自 SoapUI 的原始请求
POST http://192.168.0.28:10005/MainService/WindowsService HTTP/1.1
Accept-Encoding: gzip,deflate
Content-Type: text/xml;charset=UTF-8
SOAPAction: "http://Main.Service/AUserService/GetUsers"
Content-Length: 303
Host: 192.168.0.28:10005
Connection: Keep-Alive
User-Agent: Apache-HttpClient/4.1.1 (java 1.5)
XML from SoapUI
来自 SoapUI 的 XML
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:qtre="http://Main.Service">
<soapenv:Header/>
<soapenv:Body>
<qtre:GetUsers>
<qtre:sSearchText></qtre:sSearchText>
</qtre:GetUsers>
</soapenv:Body>
</soapenv:Envelope>
I used the above to build the following noderequest:
我用上面的来构建以下内容noderequest:
var request = require('request');
let xml =
`<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:qtre="http://Main.Service">
<soapenv:Header/>
<soapenv:Body>
<qtre:GetUsers>
<qtre:sSearchText></qtre:sSearchText>
</qtre:GetUsers>
</soapenv:Body>
</soapenv:Envelope>`
var options = {
url: 'http://192.168.0.28:10005/MainService/WindowsService?wsdl',
method: 'POST',
body: xml,
headers: {
'Content-Type':'text/xml;charset=utf-8',
'Accept-Encoding': 'gzip,deflate',
'Content-Length':xml.length,
'SOAPAction':"http://Main.Service/AUserService/GetUsers"
}
};
let callback = (error, response, body) => {
if (!error && response.statusCode == 200) {
console.log('Raw result', body);
var xml2js = require('xml2js');
var parser = new xml2js.Parser({explicitArray: false, trim: true});
parser.parseString(body, (err, result) => {
console.log('JSON result', result);
});
};
console.log('E', response.statusCode, response.statusMessage);
};
request(options, callback);
回答by Kim .J
I managed to use soap,wsdl and Node.js
You need to install soap with npm install soap
我设法使用了soap、wsdl 和Node.js 你需要安装soap npm install soap
Create a node server called server.jsthat will define soap service to be consumed by a remote client. This soap service computes Body Mass Index based on weight(kg) and height(m).
创建一个名为的节点服务器server.js,它将定义由远程客户端使用的肥皂服务。此肥皂服务根据体重 (kg) 和身高 (m) 计算身体质量指数。
const soap = require('soap');
const express = require('express');
const app = express();
/**
* this is remote service defined in this file, that can be accessed by clients, who will supply args
* response is returned to the calling client
* our service calculates bmi by dividing weight in kilograms by square of height in metres
*/
const service = {
BMI_Service: {
BMI_Port: {
calculateBMI(args) {
//console.log(Date().getFullYear())
const year = new Date().getFullYear();
const n = args.weight / (args.height * args.height);
console.log(n);
return { bmi: n };
}
}
}
};
// xml data is extracted from wsdl file created
const xml = require('fs').readFileSync('./bmicalculator.wsdl', 'utf8');
//create an express server and pass it to a soap server
const server = app.listen(3030, function() {
const host = '127.0.0.1';
const port = server.address().port;
});
soap.listen(server, '/bmicalculator', service, xml);
Next, create a client.jsfile that will consume soap service defined by server.js. This file will provide arguments for the soap service and call the url with SOAP's service ports and endpoints.
接下来,创建一个client.js将使用由 .so 定义的soap服务的文件server.js。该文件将为soap 服务提供参数,并使用SOAP 的服务端口和端点调用url。
const express = require('express');
const soap = require('soap');
const url = 'http://localhost:3030/bmicalculator?wsdl';
const args = { weight: 65.7, height: 1.63 };
soap.createClient(url, function(err, client) {
if (err) console.error(err);
else {
client.calculateBMI(args, function(err, response) {
if (err) console.error(err);
else {
console.log(response);
res.send(response);
}
});
}
});
Your wsdl file is an xml based protocol for data exchange that defines how to access a remote web service. Call your wsdl file bmicalculator.wsdl
您的 wsdl 文件是一个基于 xml 的数据交换协议,它定义了如何访问远程 Web 服务。调用您的 wsdl 文件bmicalculator.wsdl
<definitions name="HelloService" targetNamespace="http://www.examples.com/wsdl/HelloService.wsdl"
xmlns="http://schemas.xmlsoap.org/wsdl/"
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:tns="http://www.examples.com/wsdl/HelloService.wsdl"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<message name="getBMIRequest">
<part name="weight" type="xsd:float"/>
<part name="height" type="xsd:float"/>
</message>
<message name="getBMIResponse">
<part name="bmi" type="xsd:float"/>
</message>
<portType name="Hello_PortType">
<operation name="calculateBMI">
<input message="tns:getBMIRequest"/>
<output message="tns:getBMIResponse"/>
</operation>
</portType>
<binding name="Hello_Binding" type="tns:Hello_PortType">
<soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/>
<operation name="calculateBMI">
<soap:operation soapAction="calculateBMI"/>
<input>
<soap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="urn:examples:helloservice" use="encoded"/>
</input>
<output>
<soap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="urn:examples:helloservice" use="encoded"/>
</output>
</operation>
</binding>
<service name="BMI_Service">
<documentation>WSDL File for HelloService</documentation>
<port binding="tns:Hello_Binding" name="BMI_Port">
<soap:address location="http://localhost:3030/bmicalculator/" />
</port>
</service>
</definitions>
Hope it helps
希望能帮助到你
回答by Halfstop
The simplest way I found to just send raw XML to a SOAP service using Node.js is to use the Node.js http implementation. It looks like this.
我发现使用 Node.js 将原始 XML 发送到 SOAP 服务的最简单方法是使用 Node.js http 实现。它看起来像这样。
var http = require('http');
var http_options = {
hostname: 'localhost',
port: 80,
path: '/LocationOfSOAPServer/',
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'Content-Length': xml.length
}
}
var req = http.request(http_options, (res) => {
console.log(`STATUS: ${res.statusCode}`);
console.log(`HEADERS: ${JSON.stringify(res.headers)}`);
res.setEncoding('utf8');
res.on('data', (chunk) => {
console.log(`BODY: ${chunk}`);
});
res.on('end', () => {
console.log('No more data in response.')
})
});
req.on('error', (e) => {
console.log(`problem with request: ${e.message}`);
});
// write data to request body
req.write(xml); // xml would have been set somewhere to a complete xml document in the form of a string
req.end();
You would have defined the xml variable as the raw xml in the form of a string.
您可以将 xml 变量定义为字符串形式的原始 xml。
But if you just want to interact with a SOAP service via Node.js and make regular SOAP calls, as opposed to sending raw xml, use one of the Node.js libraries. I like node-soap.
但是,如果您只想通过 Node.js 与 SOAP 服务交互并进行常规 SOAP 调用,而不是发送原始 xml,请使用 Node.js 库之一。我喜欢node-soap。
回答by dam1
Depending on the number of endpoints you need it may be easier to do it manually.
根据您需要的端点数量,手动执行可能更容易。
I have tried 10 libraries "soap nodejs" I finally do it manually.
我已经尝试了 10 个库“soap nodejs”,我终于手动完成了。
- use node request (https://github.com/mikeal/request) to form input xml message to send (POST) the request to the web service
- use xml2j ( https://github.com/Leonidas-from-XIV/node-xml2js) to parse the reponse
- 使用节点请求(https://github.com/mikeal/request)形成输入xml消息以将请求发送(POST)到Web服务
- 使用 xml2j ( https://github.com/Leonidas-from-XIV/node-xml2js) 解析响应
回答by smentek
I successfully used "soap" package (https://www.npmjs.com/package/soap) on more than 10 tracking WebApis (Tradetracker, Bbelboon, Affilinet, Webgains, ...).
我成功地在 10 多个跟踪 WebApis(Tradetracker、Bbelboon、Affilinet、Webgains 等)上使用了“soap”包(https://www.npmjs.com/package/soap)。
Problems usually come from the fact that programmers does not investigate to much about what remote API needs in order to connect or authenticate.
问题通常来自这样一个事实,即程序员没有过多调查远程 API 需要什么才能连接或验证。
For instance PHP resends cookies from HTTP headers automatically, but when using 'node' package, it have to be explicitly set (for instance by 'soap-cookie' package)...
例如,PHP 会自动从 HTTP 标头重新发送 cookie,但是在使用“node”包时,必须明确设置(例如通过“soap-cookie”包)...
回答by Vince Lowe
I used the node net module to open a socket to the webservice.
我使用 node net 模块打开一个到 webservice 的套接字。
/* on Login request */
socket.on('login', function(credentials /* {username} {password} */){
if( !_this.netConnected ){
_this.net.connect(8081, '127.0.0.1', function() {
logger.gps('('+socket.id + ') '+credentials.username+' connected to: 127.0.0.1:8081');
_this.netConnected = true;
_this.username = credentials.username;
_this.password = credentials.password;
_this.m_RequestId = 1;
/* make SOAP Login request */
soapGps('', _this, 'login', credentials.username);
});
} else {
/* make SOAP Login request */
_this.m_RequestId = _this.m_RequestId +1;
soapGps('', _this, 'login', credentials.username);
}
});
Send soap requests
发送肥皂请求
/* SOAP request func */
module.exports = function soapGps(xmlResponse, client, header, data) {
/* send Login request */
if(header == 'login'){
var SOAP_Headers = "POST /soap/gps/login HTTP/1.1\r\nHost: soap.example.com\r\nUser-Agent: SOAP-client/SecurityCenter3.0\r\n" +
"Content-Type: application/soap+xml; charset=\"utf-8\"";
var SOAP_Envelope= "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" +
"<env:Envelope xmlns:env=\"http://www.w3.org/2003/05/soap-envelope\" xmlns:SOAP-ENC=\"http://www.w3.org/2003/05/soap-encoding\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:n=\"http://www.example.com\"><env:Header><n:Request>" +
"Login" +
"</n:Request></env:Header><env:Body>" +
"<n:RequestLogin xmlns:n=\"http://www.example.com.com/gps/soap\">" +
"<n:Name>"+data+"</n:Name>" +
"<n:OrgID>0</n:OrgID>" +
"<n:LoginEntityType>admin</n:LoginEntityType>" +
"<n:AuthType>simple</n:AuthType>" +
"</n:RequestLogin></env:Body></env:Envelope>";
client.net.write(SOAP_Headers + "\r\nContent-Length:" + SOAP_Envelope.length.toString() + "\r\n\r\n");
client.net.write(SOAP_Envelope);
return;
}
Parse soap response, i used module - xml2js
解析肥皂响应,我使用了模块 - xml2js
var parser = new xml2js.Parser({
normalize: true,
trim: true,
explicitArray: false
});
//client.net.setEncoding('utf8');
client.net.on('data', function(response) {
parser.parseString(response);
});
parser.addListener('end', function( xmlResponse ) {
var response = xmlResponse['env:Envelope']['env:Header']['n:Response']._;
/* handle Login response */
if (response == 'Login'){
/* make SOAP LoginContinue request */
soapGps(xmlResponse, client, '');
}
/* handle LoginContinue response */
if (response == 'LoginContinue') {
if(xmlResponse['env:Envelope']['env:Body']['n:ResponseLoginContinue']['n:ErrCode'] == "ok") {
var nTimeMsecServer = xmlResponse['env:Envelope']['env:Body']['n:ResponseLoginContinue']['n:CurrentTime'];
var nTimeMsecOur = new Date().getTime();
} else {
/* Unsuccessful login */
io.to(client.id).emit('Error', "invalid login");
client.net.destroy();
}
}
});
Hope it helps someone
希望它可以帮助某人
回答by euroblaze
You may also look at the easysoap npm - https://www.npmjs.org/package/easysoap-or- some of these: https://nodejsmodules.org/tags/soap
您还可以查看 easysoap npm - https://www.npmjs.org/package/easysoap- 或其中一些:https: //nodejsmodules.org/tags/soap
回答by J.Aliaga
Adding to Kim .J's solution: you can add preserveWhitespace=truein order to avoid a Whitespace error. Like this:
添加到Kim .J 的解决方案:您可以添加preserveWhitespace=true以避免出现空白错误。像这样:
soap.CreateClient(url,preserveWhitespace=true,function(...){

