带有Node.js和SOAP的SOAP争论传播

时间:2018-01-29 13:27:18

标签: node.js soap

我必须使用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,而不是作为对象。 使用node的soap客户端(node-soap或strong-soap),参数2必须是回调函数,它可以提供如下代码:(让我们说文档给我字段1应该是& #39;登录&#39;等)

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的SOAP请求在格式上确实不同。 所以我通过使用&#34; request&#34;更简单(并且,不幸的是,更脏)。来自节点的lib并从正在运行的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);
}));

然后只需使用您最喜欢的比较器来查看您的通话之间的差异。

1 个答案:

答案 0 :(得分:0)

我已经测试了链接中提供的WSDL,对Ajout_BDD过程的SOAP调用将涉及一个如下所示的HTTP帖子:

<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  xmlns:typens="urn:mdworks">
    <soap:Body>
        <typens:Ajout_BDD>
            <login>loginValue</login>
            <moddepasse>moddepasseValue</moddepasse>
            <bdd>bddValue</bdd>
            <ligne>
                <typens:someField>someFieldValue</typens:someField>
            </ligne>
        </typens:Ajout_BDD>
    </soap:Body>
</soap:Envelope>

响应应如下所示:

<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"  xmlns:typens="urn:mdworks">
    <soap:Body>
        <typens:Ajout_BDDResponse>
            <typens:output>
                <typens:Ajout_BDDReturn>true</typens:Ajout_BDDReturn>
            </typens:output>
        </typens:Ajout_BDDResponse>
    </soap:Body>
</soap:Envelope>

对于需要PHP客户端调用它的服务,应该没有任何具体内容。在Node.js中,您的客户端代码应如下所示:

"use strict";

var url = 'http://localhost:8001/mdworksService';
var wsdlFileName = 'example-service-original.wsdl';

const soap = require('soap');
const path = require('path');

soap
    .createClientAsync(path.join(__dirname, wsdlFileName), {endpoint: url})
    .then((client) => client.Ajout_BDD({
        login: 'loginValue', moddepasse: 'moddepasseValue', bdd: 'bddValue', ligne: { someField: 'someFieldValue'}
    }, (error, result) => {
        if (error) {
            console.error(error);
            process.exit(1);
        }
        console.log(result);
        process.exit(0);
    }))
    .catch( (error) => {
        console.error(error);
        process.exit(1);
    });

您需要将url替换为服务的实际URL,并创建WSDL文件(使用您链接到的WSDL)。为了测试客户端代码,可以轻松地创建此服务的Node.js模拟。你可以这样做:

"use strict";

var soap = require('soap');
var http = require('http');

var service = {
    mdworksService: {
        MDWORKSPort: {
            Ajout_BDD : function(args) {
                console.log('Calling Ajout_BDD: args: ' + JSON.stringify(args));
                return { output: { Ajout_BDDReturn : true } };
            }
        }
    }
}

var xml = require('fs').readFileSync('example-service-original.wsdl', 'utf8');

var server = http.createServer(function(request,response) {
    response.end("404: Not Found: "+request.url);
});

server.listen(8001);
var soapServer = soap.listen(server, '/mdworksService', service, xml);
soapServer.log = function(type, data) {
    // type is 'received' or 'replied'
    console.log(new Date().toISOString() + ": " + type + ': ' + data);
};

同样,您需要将WSDL文件包含在与服务器相同的目录中。这种方法对于测试SOAP客户端非常有用。