【问题标题】:nodeJs soap libarary can not send request to wsdl urlnodeJs 肥皂库无法向 wsdl url 发送请求
【发布时间】:2018-07-11 14:38:23
【问题描述】:

我有一个像 https://example.com/TokenService?wsdl 这样的 SOAP API, 我在以下函数中发送创建 Client 的请求:

let soap = require('soap');
   soap.createClient(url, function(err, client) {
       console.log('err is ',err) ;
        client.myFunction(input_params, function(err, result) {
            console.log(result);

        });
    });

然后我收到这样的错误:

错误:ENOENT:没有这样的文件或目录,打开'https:///example.com//TokenService?wsdl'
错误号:-2,
代码:'ENOENT',
系统调用:'打开',
路径:'https://example.com/TokenService?wsdl`

而我的客户是不受约束的。

【问题讨论】:

    标签: javascript node.js soap wsdl


    【解决方案1】:

    我想你快到了。下面是一个可以测试的调用示例:

    const soap = require('soap');
    
    const url = 'http://www.webservicex.net/globalweather.asmx';
    const wsdlURL = 'http://www.webservicex.net/globalweather.asmx?WSDL';
    
    soap.createClient(wsdlURL, {endpoint: url}, function(error, client) {
        if (error) {
            console.error(error);
        } else {
            client.GetCitiesByCountry({ CountryName: 'Russian Federation'}, function(error, result) {
                if (error) {
                    console.error(error);
                    process.exit(1);
                }
                console.log(result);
            });
        }
    });
    

    我认为您可能只需要将两个 url 传递给函数,即服务 url 和 WSDL url。有时您不需要这样做,WSDL 将包含所有操作 URL 的链接。如果您省略 {endpoint: url } 选项,有些调用会起作用,而有些则不会。

    还要检查 WSDL 链接,确保 WSDL 有效,您可以在浏览器中查看,应该如下所示:

    http://www.webservicex.net/globalweather.asmx?WSDL

    您也可以将 WSDL 下载到文件中并尝试:

    "use strict";
    
    const wsdlFileName = 'globalweather.wsdl';
    const path = require('path');
    const wsdlFile = path.join(__dirname, wsdlFileName);
    
    const soap = require('soap');
    
    const url = 'http://www.webservicex.net/globalweather.asmx';
    
    soap.createClient(wsdlFile, {endpoint: url}, function(error, client) {
        if (error) {
            console.error(error);
        } else {
            client.GetCitiesByCountry({ CountryName: 'Russian Federation'}, function(error, result) {
                if (error) {
                    console.error(error);
                    process.exit(1);
                }
                console.log(result);
            });
        }
    });
    

    您需要将 WSDL 文件与您的脚本放在同一目录中。

    我知道这可以在 C# 客户端中工作吗,XML POST 看起来像这样:

    <s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
        <s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
            <reservation xmlns="http://token.ws.web.cnpg/">
                <Token_param xmlns="">
                    <AMOUNT>amount</AMOUNT>
                    <CRN>crn</CRN>
                    <MID>mid</MID>
                    <REFERALADRESS>referaladdress</REFERALADRESS>
                    <SIGNATURE>signature</SIGNATURE>
                    <TID>tid</TID>
                </Token_param>
            </reservation>
        </s:Body>
    </s:Envelope>
    

    然后回应:

    <S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
        <S:Body>
            <ns2:reservationResponse xmlns:ns2="http://token.ws.web.cnpg/">
                <return>
                    <result>3</result>
                    <token>Security check was not successful.</token>
                </return>
            </ns2:reservationResponse>
        </S:Body>
    </S:Envelope>
    

    我可以通过执行以下操作对该地址进行 POST:

    var request = require('request');
    var url = 'https://example.com/TokenService';
    var tokenXML = `<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
            <s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
                <reservation xmlns="http://token.ws.web.cnpg/">
                    <Token_param xmlns="">
                        <AMOUNT>amount</AMOUNT>
                        <CRN>crn</CRN>
                        <MID>mid</MID>
                        <REFERALADRESS>referaladdress</REFERALADRESS>
                        <SIGNATURE>signature</SIGNATURE>
                        <TID>tid</TID>
                    </Token_param>
                </reservation>
            </s:Body>
        </s:Envelope>`;
    
    console.log('Posting..')
    console.log(tokenXML);
    request.post(
        {url: url,
        body : tokenXML,
        headers: {'Content-Type': 'text/xml'}
        }, function optionalCallback(err, httpResponse, body) {
      if (err) {
        return console.error('upload failed:', err);
      }
      console.log('Upload successful!  Server responded with:', body);
    });
    

    由于某种原因,NPM soap 库不喜欢这个 web 服务! 但是您可以自己填写 XML 中的值,如果您有需要填写的详细信息,可能会更进一步。

    我收到了回复:

    <S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
        <S:Body>
            <ns2:reservationResponse xmlns:ns2="http://token.ws.web.cnpg/">
                <return>
                    <result>3</result>
                    <token>Security check was not successful.</token>
                </return>
            </ns2:reservationResponse>
        </S:Body>
    </S:Envelope>
    

    但我可能没有用户名密码。如果您可以填写这些详细信息,也许您会得到成功的回复。顺便说一句,您需要执行 NPM 安装请求以获取请求库。

    【讨论】:

    • 我通过 https://example.com 和 wsdl url https://example.com/TokenService?wsdl 之类的 url 进行了测试,但显示相同的错误。我检查了我的 wsdl url 并且是有效的。
    • 好的,我可以看到对象模型,但这不包含我可以测试的 Url..据我所知。看起来由于某种原因节点服务无法访问 WSDL Url。您是否尝试将 NODE_DEBUG 设置为 net、tls 等以在日志中显示更多错误?这值得一试,您可能会了解更多为什么这不起作用:juliengilli.com/2013/05/26/…
    • 我看看能不能修好!
    • 我认为使用 XML 帖子可能比使用 SOAP 库更容易,我只是在创建客户端时遇到错误。我已经更新了我的答案以显示 POSTing the raw XML。
    • 谢谢。这种方法解决了我的问题。 Soap 插件可能有问题。
    猜你喜欢
    • 2017-01-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-15
    相关资源
    最近更新 更多