在Node-soap(node.js)中使用数组发送请求

时间:2015-03-04 21:16:41

标签: javascript node.js node-soap

我正在使用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"];

并且我得到了响应“用户id为空”(uuid)

 var auth = {'uuid': 'XXXXXXXXX'};

有什么建议吗?

3 个答案:

答案 0 :(得分:3)

我无能为力,但这里有一些提示可以帮助你入门。

  1. 使用client.describe()查看服务如何期望参数。
  2. 您尝试访问的服务具有以下结构:

    { 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 /肥皂/ LIB / client.js

    在设置消息后立即在第187行添加console.log

    console.log("Message! ", message);
    

    这将显示消息,该消息应该为您提供足够的信息以确定参数的格式。

答案 1 :(得分:3)

最后使用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 for this:

    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\" " +

希望这可能对使用此库并处于这种情况的人有所帮助。

答案 2 :(得分:1)

已经过去了几年,但是我还有另一个建议来解决这个问题。 如果您(像我一样)不了解所有名称空间(由于缺乏理解),则可以将序列化的XML字符串直接放入这样的值中:

var objToSend = {
  someString: 'stringVal',
  arrayContent: {
    $xml: '<item>val1</item><item>val2</item>'
  }
}
相关问题