在 Node-soap 中发送带有数组的请求 (node.js)
Send a request with arrays in Node-soap (node.js)
我正在使用 nodejs 和 node-soap 与 Web 服务通信。但我似乎无法获得将参数传递给服务的正确语法。
文档说我需要发送一个包含字段 uuid 及其值的数组。
这是我从网络服务所有者那里得到的示例代码Php
$uuid = "xxxx";
$param = array("uuid"=>new SoapVar($uuid,
XSD_STRING,
"string", "http://www.w3.org/2001/XMLSchema")
)
这是我在节点服务器中使用的代码
function getSoapResponse()
{
var soap = require('soap');
var url = 'http://live.pagoagil.net/soapserver?wsdl';
var auth = [{'uuid': 'XXXXXXXXX'}];
soap.createClient(url, function(err, client) {
client.ListaBancosPSE(auth, function(err, result)
{
console.log(result);
console.log(err);
});
});
有了这个我就变坏了xml错误
var auth = [{'uuid': 'XXXXXXXXX'}];
或
var auth = [["uuid",key1],XSD_STRING,"string","http://www.w3.org/2001/XMLSchema"];
然后我得到响应"the user id is empty"(uuid)
var auth = {'uuid': 'XXXXXXXXX'};
有什么建议吗?
我能为您做的不多,但这里有一些提示可以帮助您入门。
- 使用 client.describe() 查看服务如何期望参数。
您尝试访问的服务具有以下结构:
{ App_SoapService:
{ App_SoapPort:
{ Autorizar: [Object],
AutorizarAdvance: [Object],
AutorizarIac: [Object],
ListaBancosPSE: [Object],
AutorizarPSE: [Object],
AutorizarTuya: [Object],
AutorizarBotonCredibanco: [Object],
FinalizarPSE: [Object],
FinalizarTuya: [Object],
ConsultarReferencia: [Object] } } }
仔细查看 ListaBancosPSE 的具体方法,它提供了以下信息:
{input: { auth: 'soap-enc:Array' },
output: { return: 'soap-enc:Array' }}
我试过这个:
var soap = require('soap');
function getSoapResponse(url, auth) {
soap.createClient(url, function(err, client) {
console.log(client.describe());
console.log(client.describe().App_SoapService.App_SoapPort.ListaBancosPSE);
client.ListaBancosPSE(auth, function(err, result) {
console.log(JSON.stringify(result));
console.log(err);
});
});
}
getSoapResponse('http://live.pagoagil.net/soapserver?wsdl', {'soap-enc:Array' : {'uuid': 'XXXXXXXXX'}});
响应相同"Negada, Error nombre de usuario vacio, No se pudo autenticar en pagoagil.net."。
您的下一步是确定服务期望的消息。
可能是这样的:
<tns:ListaBancosPSE><uuid>XXXXXXXXX</uuid></tns:ListaBancosPSE>
或
<tns:ListaBancosPSE><soap-enc:Array><uuid>XXXXXXXXX</uuid></soap-enc:Array></tns:ListaBancosPSE>
一旦你知道了,你只需要在你安装的 node-soap 包中添加一个 console.log,所以去你安装 node_modules 的地方并打开文件
node_modules/soap/lib/client.js
在第 187 行添加一个 console.log,紧接在设置消息之后
console.log("Message! ", message);
这将显示消息,它应该为您提供足够的信息来确定参数的格式。
最终使用this答案中的内容并修改soap-node模块中的代码,我能够获得我需要的代码。
我需要这样的东西:
<auth xsi:type="ns2:Map">
<item>
<key xsi:type="xsd:string">uuid</key>
<value xsi:type="xsd:string">{XXXXXX}</value>
</item>
</auth>
所以我用它来创建参数:
var arrayToSend=
{auth :
[
{ 'attributes' : {'xsi:type':"ns2:Map"},
'item':
[
{'key' :
{'attributes' :
{ 'xsi:type': 'xsd:string'},
$value: 'uuid'
}
},
{'value' :
{'attributes' :
{ 'xsi:type': 'xsd:string'},
$value: uuid
}
}
]
}
]
};
然后这样发送:
soap.createClient(url, myFunction);
function myFunction(err, client)
{
client.ListaBancosPSE(arrayToSend,function(err, result)
{
console.log('\n' + result);
});
}
然后棘手的部分是修改 wsd.js
所以它没有在我每次使用和数组时添加额外的标签。我转到第 1584 行并为此更改了 if:
if (Array.isArray(obj))
{
var arrayAttr = self.processAttributes(obj[0]),
correctOuterNamespace = parentNamespace || ns; //using the parent namespace if given
parts.push(['<', correctOuterNamespace, name, arrayAttr, xmlnsAttrib, '>'].join(''));
for (var i = 0, item; item = obj[i]; i++)
{
parts.push(self.objectToXML(item, name, namespace, xmlns, false, null, parameterTypeObject, ancXmlns));
}
parts.push(['</', correctOuterNamespace, name, '>'].join(''));
}
基本上现在它不会在每个迭代中推送打开和关闭标签,而是只在整个循环之前和之后推送。
我还需要为消息的 xlmns 添加定义。 Client.js:186
xml = "<soap:Envelope " +
"xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\" " +
'xmlns:xsd="http://www.w3.org/2001/XMLSchema"' +
'xmlns:ns2="http://xml.apache.org/xml-soap"' +
"xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" " +
希望这对使用这个库的人和处于这种情况的人有所帮助。
几年过去了,但我有另一个解决这个问题的建议。
如果你(像我一样)不了解所有命名空间的东西(由于缺乏理解),你可以直接将序列化的 XML 字符串放入这样的值中:
var objToSend = {
someString: 'stringVal',
arrayContent: {
$xml: '<item>val1</item><item>val2</item>'
}
}
我正在使用 nodejs 和 node-soap 与 Web 服务通信。但我似乎无法获得将参数传递给服务的正确语法。
文档说我需要发送一个包含字段 uuid 及其值的数组。
这是我从网络服务所有者那里得到的示例代码Php
$uuid = "xxxx";
$param = array("uuid"=>new SoapVar($uuid,
XSD_STRING,
"string", "http://www.w3.org/2001/XMLSchema")
)
这是我在节点服务器中使用的代码
function getSoapResponse()
{
var soap = require('soap');
var url = 'http://live.pagoagil.net/soapserver?wsdl';
var auth = [{'uuid': 'XXXXXXXXX'}];
soap.createClient(url, function(err, client) {
client.ListaBancosPSE(auth, function(err, result)
{
console.log(result);
console.log(err);
});
});
有了这个我就变坏了xml错误
var auth = [{'uuid': 'XXXXXXXXX'}];
或
var auth = [["uuid",key1],XSD_STRING,"string","http://www.w3.org/2001/XMLSchema"];
然后我得到响应"the user id is empty"(uuid)
var auth = {'uuid': 'XXXXXXXXX'};
有什么建议吗?
我能为您做的不多,但这里有一些提示可以帮助您入门。
- 使用 client.describe() 查看服务如何期望参数。
您尝试访问的服务具有以下结构:
{ App_SoapService:
{ App_SoapPort:
{ Autorizar: [Object],
AutorizarAdvance: [Object],
AutorizarIac: [Object],
ListaBancosPSE: [Object],
AutorizarPSE: [Object],
AutorizarTuya: [Object],
AutorizarBotonCredibanco: [Object],
FinalizarPSE: [Object],
FinalizarTuya: [Object],
ConsultarReferencia: [Object] } } }
仔细查看 ListaBancosPSE 的具体方法,它提供了以下信息:
{input: { auth: 'soap-enc:Array' },
output: { return: 'soap-enc:Array' }}
我试过这个:
var soap = require('soap');
function getSoapResponse(url, auth) {
soap.createClient(url, function(err, client) {
console.log(client.describe());
console.log(client.describe().App_SoapService.App_SoapPort.ListaBancosPSE);
client.ListaBancosPSE(auth, function(err, result) {
console.log(JSON.stringify(result));
console.log(err);
});
});
}
getSoapResponse('http://live.pagoagil.net/soapserver?wsdl', {'soap-enc:Array' : {'uuid': 'XXXXXXXXX'}});
响应相同"Negada, Error nombre de usuario vacio, No se pudo autenticar en pagoagil.net."。
您的下一步是确定服务期望的消息。
可能是这样的:
<tns:ListaBancosPSE><uuid>XXXXXXXXX</uuid></tns:ListaBancosPSE>
或
<tns:ListaBancosPSE><soap-enc:Array><uuid>XXXXXXXXX</uuid></soap-enc:Array></tns:ListaBancosPSE>
一旦你知道了,你只需要在你安装的 node-soap 包中添加一个 console.log,所以去你安装 node_modules 的地方并打开文件
node_modules/soap/lib/client.js
在第 187 行添加一个 console.log,紧接在设置消息之后
console.log("Message! ", message);
这将显示消息,它应该为您提供足够的信息来确定参数的格式。
最终使用this答案中的内容并修改soap-node模块中的代码,我能够获得我需要的代码。
我需要这样的东西:
<auth xsi:type="ns2:Map">
<item>
<key xsi:type="xsd:string">uuid</key>
<value xsi:type="xsd:string">{XXXXXX}</value>
</item>
</auth>
所以我用它来创建参数:
var arrayToSend=
{auth :
[
{ 'attributes' : {'xsi:type':"ns2:Map"},
'item':
[
{'key' :
{'attributes' :
{ 'xsi:type': 'xsd:string'},
$value: 'uuid'
}
},
{'value' :
{'attributes' :
{ 'xsi:type': 'xsd:string'},
$value: uuid
}
}
]
}
]
};
然后这样发送:
soap.createClient(url, myFunction);
function myFunction(err, client)
{
client.ListaBancosPSE(arrayToSend,function(err, result)
{
console.log('\n' + result);
});
}
然后棘手的部分是修改 wsd.js
所以它没有在我每次使用和数组时添加额外的标签。我转到第 1584 行并为此更改了 if:
if (Array.isArray(obj))
{
var arrayAttr = self.processAttributes(obj[0]),
correctOuterNamespace = parentNamespace || ns; //using the parent namespace if given
parts.push(['<', correctOuterNamespace, name, arrayAttr, xmlnsAttrib, '>'].join(''));
for (var i = 0, item; item = obj[i]; i++)
{
parts.push(self.objectToXML(item, name, namespace, xmlns, false, null, parameterTypeObject, ancXmlns));
}
parts.push(['</', correctOuterNamespace, name, '>'].join(''));
}
基本上现在它不会在每个迭代中推送打开和关闭标签,而是只在整个循环之前和之后推送。
我还需要为消息的 xlmns 添加定义。 Client.js:186
xml = "<soap:Envelope " +
"xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\" " +
'xmlns:xsd="http://www.w3.org/2001/XMLSchema"' +
'xmlns:ns2="http://xml.apache.org/xml-soap"' +
"xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" " +
希望这对使用这个库的人和处于这种情况的人有所帮助。
几年过去了,但我有另一个解决这个问题的建议。 如果你(像我一样)不了解所有命名空间的东西(由于缺乏理解),你可以直接将序列化的 XML 字符串放入这样的值中:
var objToSend = {
someString: 'stringVal',
arrayContent: {
$xml: '<item>val1</item><item>val2</item>'
}
}