【发布时间】:2018-01-29 13:27:18
【问题描述】:
我必须使用一个 SOAP API,它基本上是为 PHP 设计的,并且一直是 PHP 客户端的用户。问题是,我使用 Node.js,遇到了一个我无法处理的问题。 这是“可能工作”代码的一部分:
<?php
try {
$client = new SoapClient(null, array(
'location' => "https://my-soap-server.com/_soap/server.php",
'uri' => "https://my-soap-server.com",
'encoding' => 'ISO-8859-1'
));
$result = $client->myMethod('aaaa', 'bbbb', 'cccc');
var_dump($result);
}
catch (SoapFault $fault) {
trigger_error("SOAP Fault: (faultcode: {$fault->faultcode}, faultstring:{$fault->faultstring})", E_USER_ERROR);
}
如您所见,参数以特定顺序传递给 myMethod,而不是作为对象。 使用节点的肥皂客户端(节点肥皂或强肥皂),参数 2 必须是回调,它可以给出非常像这样的代码:(假设文档给我的字段 1 应该是“登录”等)
const soap = require('soap');
soap
.createClientAsync('http://my-soap-server.com')
.then((client) => client.myMethod({
login: 'aaaa',
password: 'bbbb',
randomVar: 'cccc',
}, (error, result) => {
if (error) {
console.error(error);
process.exit(1);
}
console.log(result);
process.exit(0);
})
.catch((error) => {
console.error(error);
process.exit(1);
});
好吧,我没有任何错误,但 API 没有按照预期执行。 所以,我想问题是服务器不期望一个带有键的对象,而是参数,按一定的顺序传播,就像在 PHP 中一样。有没有办法用 Node.js 重现它?
我希望我已经足够清楚了。
非常感谢您的帮助。
编辑:使用WSDL 可能更容易,我想要使用的方法是 Ajout_BDD。
编辑 2:好吧,经过进一步调查,看起来来自 PHP 的 SOAP 请求和来自 Node.js 的请求在格式上确实不同。 因此,我通过使用来自节点的“请求”库并从工作的 PHP 请求制作模板,使它变得更简单(不幸的是,更脏)。 仅供参考,您可以使用以下代码转储 PHP SOAP 请求:
$client = new SoapClient("http://127.0.0.1:2018/test/test2?WSDL", array(
'trace' => 1
));
[...]
var_dump($client->__getLastRequest());
您也可以通过这种方式转储 Node SOAP 请求:
soap.createClientAsync('http://my-soap-server/hello?WSDL', (error, client) => client.myMethod({
login: 'aaaa',
password: 'bbbb',
randomVar: 'cccc',
}, (error, result) => {
[...]
console.log(client.lastRequest);
}));
然后只需使用您最喜欢的比较器来查看您的调用之间有什么不同。
【问题讨论】:
-
这是一个棘手的问题,如果无法访问相关服务,很难准确看出 Node.js SOAP 请求的问题所在。在这种情况下真正有用的是查看实际 Web 流量的踪迹。像 WireShark 这样的东西在这里真的很有用,你可以看到你从 PHP 发出的请求是什么样的,并将它与你在 Node.js 中的请求进行比较。我遇到过这样的问题,我可以很快看出这两个 SOAP 调用之间有什么不同。
-
这是解决问题的好方法,能够检查确切的 SOAP 请求以查看差异是很有用的。