肥皂库发送错误的XML请求

时间:2018-02-07 16:51:30

标签: javascript node.js

我在node.js中使用此库来进行SOAP API调用:https://github.com/vpulim/node-soap

以下是wsdl和xsd文件供参考: https://drive.google.com/open?id=1ha7CqyJBnkISsI0wafwVrV4qG813ML64

这些呼叫正在向Cisco CUCM(VOIP应用服务器)发出。为了给出上下文,它所要做的就是使用getPhone方法获取特定手机的详细信息,在此示例中使用设备名称SEPAAAABBBBCCCC。这是代码:

var soap = require("soap");

var url = "AXLAPI.wsdl";
var auth = "Basic " + new Buffer("axl" + ":" + "cisco").toString("base64");
var args = {
name: "SEPAAAABBBBCCCC"
};

soap.createClient(url, function(err, client) {
   client.setEndpoint("https://192.168.138.15:8443/axl");
   client.addHttpHeader("Authorization", auth);
   client.setSecurity(new soap.ClientSSLSecurity(undefined,undefined, undefined, {rejectUnauthorized: false,},));

   client.getPhone(args, function(err,result) {
       if (err) {
           console.log("soap api error is: " + err);
           console.log("last request: " + client.lastRequest);
           process.exit(1);
       }

   console.log("result is: " + result);
   });

   if (err) {
      console.log("soap client error is: " + err);
   }
});

它无法正常工作。打印到控制台日志的错误不是很有用。它只是说明:"错误:无法解析响应。"

该库具有可以记录XML请求的功能(代码中的client.lastRequest)。这是我得到的输出:

<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:s0="http://www.cisco.com/AXLAPIService/" xmlns:tm="http://microsoft.com/wsdl/mime/textMatching/" xmlns:xsd1="http://www.cisco.com/AXL/API/11.5">
<soap:Header></soap:Header>
    <soap:Body>
        <getPhoneIn>
            <name>SEPAAAABBBBCCCC</name>
        </getPhoneIn>
    </soap:Body>
</soap:Envelope>

但这不正确。如果我使用postman手动发送带有上述主体的AXL请求,我会收到此错误字符串:

<faultstring>error: The document is not a getPhone@http://www.cisco.com/AXL/API/11.5: document element mismatch got getPhoneIn</faultstring>

我不确定该库如何获取getPhoneIn元素,因为它对WSDL文件无效。它应该是getPhone。

编辑:我发布了我使用的解决方案,因此可以帮助其他人(感谢Terry的出色支持和输入)

"use-strict";

var soap = require("strong-soap").soap;
var request = require("request");


var url = "AXLAPI.wsdl";

var auth = "Basic " + new Buffer("axl" + ":" + "cisco").toString("base64");

var requestArgs = {
    name:  "SEPAAAABBBBCCCC"
};

var specialRequest = request.defaults({ strictSSL: false });

var options = { 
              endpoint:  "https://192.168.138.15:8443/axl/",
              request: specialRequest
          };

soap.createClient(url, options, function(err, client) { 
    client.addHttpHeader("Authorization", auth);

    var method = client.getPhone;
    method(requestArgs, function (err, result, envelope, soapHeader) {
        console.log("Result: " + JSON.stringify(result));
    });
});

1 个答案:

答案 0 :(得分:1)

我不确定这对你有多大帮助,但我用强力肥皂库测试了这个,你得到以下信封:

<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
  <soap:Header/>
  <soap:Body>
    <ns1:getPhone xmlns:ns1="http://www.cisco.com/AXL/API/11.5">
      <name>test_name</name>
    </ns1:getPhone>
  </soap:Body>
</soap:Envelope>

代码如下:

"use strict";

var soap = require('strong-soap').soap;
var request = require("request");

// wsdl of the web service this client is going to invoke. For local wsdl you can use, url = './wsdls/stockquote.wsdl'
var url = './AXLAPI.wsdl';

// Use this to intercept calls from strong-soap if we want to fiddle with anything..
var stubRequest = (requestOptions, callbackFn) => { 
    console.log("Strong-Soap-Call-To-Request: ", requestOptions, callbackFn);
    // Here you can change the HTTP method.. but don't do this if it's pulling the WSDL
    if ((requestOptions.uri.search || "").toLowerCase() !== "?wsdl") {
        console.log("Strong-Soap-Call-To-Request: Changing HTTP method");
        requestOptions.method = 'POST';
    }

    console.log("Strong-Soap-Call-To-Request-After-Mods: ", requestOptions, callbackFn);
    request(requestOptions, callbackFn);
};
var options = { endpoint: 'put service url here', request: stubRequest};
var requestArgs = { name: 'test_name' };
soap.createClient(url, options, function(err, client) {
  var method = client.getPhone;
  method(requestArgs, function(err, result, envelope, soapHeader) {
    //response envelope
    console.log('Response Envelope: \n' + envelope);
    //'result' is the response body
    console.log('Result: \n' + JSON.stringify(result));
  });
});

您需要在options对象中设置端点。此外,还需要auth标头。

describe方法也很有用:

// Describes the entire WSDL in a JSON tree object form.
var description = client.describe();
相关问题