Node.js:如何使用 SOAP XML Web 服务

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/8655252/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 14:56:06  来源:igfitidea点击:

Node.js: how to consume SOAP XML web service

xmlnode.jssoap

提问by WHITECOLOR

I wonder what is the best way to consume SOAP XML web service with node.js

我想知道使用 node.js 使用 SOAP XML Web 服务的最佳方式是什么

Thanks!

谢谢!

采纳答案by Juicy Scripter

You don't have that many options.

你没有那么多选择。

You'll probably want to use one of:

您可能想要使用以下之一:

回答by tmanolatos

I think that an alternative would be to:

我认为另一种选择是:

Yes, this is a rather dirty and low level approach but it should work without problems

是的,这是一种相当肮脏和低级的方法,但它应该可以正常工作

回答by jtlindsey

If node-soapdoesn't work for you, just use noderequestmodule and then convert the xml to json if needed.

如果node-soap不适合您,只需使用noderequest模块,然后根据需要将 xml 转换为 json。

My request wasn't working with node-soapand there is no support for that module beyond the paid support, which was beyond my resources. So i did the following:

我的请求不起作用,node-soap除了付费支持之外,没有对该模块的支持,这超出了我的资源范围。所以我做了以下事情:

  1. downloaded SoapUIon my Linux machine.
  2. copied the WSDL xml to a local file
    curl http://192.168.0.28:10005/MainService/WindowsService?wsdl > wsdl_file.xml
  3. In SoapUI I went to File > New Soap projectand uploaded my wsdl_file.xml.
  4. In the navigator i expanded one of the services and right clicked the request and clicked on Show Request Editor.
  1. 在我的 Linux 机器上下载了SoapUI
  2. 将 WSDL xml 复制到本地文件
    curl http://192.168.0.28:10005/MainService/WindowsService?wsdl > wsdl_file.xml
  3. 在 SoapUI 中,我去File > New Soap project上传了我的wsdl_file.xml.
  4. 在导航器中,我展开了一项服务并右键单击请求并单击Show Request Editor

From there I could send a request and make sure it worked and I could also use the Rawor HTMLdata to help me build an external request.

从那里我可以发送请求并确保它有效,我也可以使用RawHTML数据来帮助我构建外部请求。

Raw from SoapUI for my request

来自 SoapUI 的原始请求

POST http://192.168.0.28:10005/MainService/WindowsService HTTP/1.1
Accept-Encoding: gzip,deflate
Content-Type: text/xml;charset=UTF-8
SOAPAction: "http://Main.Service/AUserService/GetUsers"
Content-Length: 303
Host: 192.168.0.28:10005
Connection: Keep-Alive
User-Agent: Apache-HttpClient/4.1.1 (java 1.5)

XML from SoapUI

来自 SoapUI 的 XML

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:qtre="http://Main.Service">
   <soapenv:Header/>
   <soapenv:Body>
      <qtre:GetUsers>
         <qtre:sSearchText></qtre:sSearchText>
      </qtre:GetUsers>
   </soapenv:Body>
</soapenv:Envelope> 

I used the above to build the following noderequest:

我用上面的来构建以下内容noderequest

var request = require('request');
let xml =
`<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:qtre="http://Main.Service">
   <soapenv:Header/>
   <soapenv:Body>
      <qtre:GetUsers>
         <qtre:sSearchText></qtre:sSearchText>
      </qtre:GetUsers>
   </soapenv:Body>
</soapenv:Envelope>`

var options = {
  url: 'http://192.168.0.28:10005/MainService/WindowsService?wsdl',
  method: 'POST',
  body: xml,
  headers: {
    'Content-Type':'text/xml;charset=utf-8',
    'Accept-Encoding': 'gzip,deflate',
    'Content-Length':xml.length,
    'SOAPAction':"http://Main.Service/AUserService/GetUsers"
  }
};

let callback = (error, response, body) => {
  if (!error && response.statusCode == 200) {
    console.log('Raw result', body);
    var xml2js = require('xml2js');
    var parser = new xml2js.Parser({explicitArray: false, trim: true});
    parser.parseString(body, (err, result) => {
      console.log('JSON result', result);
    });
  };
  console.log('E', response.statusCode, response.statusMessage);  
};
request(options, callback);

回答by Kim .J

I managed to use soap,wsdl and Node.js You need to install soap with npm install soap

我设法使用了soap、wsdl 和Node.js 你需要安装soap npm install soap

Create a node server called server.jsthat will define soap service to be consumed by a remote client. This soap service computes Body Mass Index based on weight(kg) and height(m).

创建一个名为的节点服务器server.js,它将定义由远程客户端使用的肥皂服务。此肥皂服务根据体重 (kg) 和身高 (m) 计算身体质量指数。

const soap = require('soap');
const express = require('express');
const app = express();
/**
 * this is remote service defined in this file, that can be accessed by clients, who will supply args
 * response is returned to the calling client
 * our service calculates bmi by dividing weight in kilograms by square of height in metres
 */
const service = {
  BMI_Service: {
    BMI_Port: {
      calculateBMI(args) {
        //console.log(Date().getFullYear())
        const year = new Date().getFullYear();
        const n = args.weight / (args.height * args.height);
        console.log(n);
        return { bmi: n };
      }
    }
  }
};
// xml data is extracted from wsdl file created
const xml = require('fs').readFileSync('./bmicalculator.wsdl', 'utf8');
//create an express server and pass it to a soap server
const server = app.listen(3030, function() {
  const host = '127.0.0.1';
  const port = server.address().port;
});
soap.listen(server, '/bmicalculator', service, xml);

Next, create a client.jsfile that will consume soap service defined by server.js. This file will provide arguments for the soap service and call the url with SOAP's service ports and endpoints.

接下来,创建一个client.js将使用由 .so 定义的soap服务的文件server.js。该文件将为soap 服务提供参数,并使用SOAP 的服务端口和端点调用url。

const express = require('express');
const soap = require('soap');
const url = 'http://localhost:3030/bmicalculator?wsdl';
const args = { weight: 65.7, height: 1.63 };
soap.createClient(url, function(err, client) {
  if (err) console.error(err);
  else {
    client.calculateBMI(args, function(err, response) {
      if (err) console.error(err);
      else {
        console.log(response);
        res.send(response);
      }
    });
  }
});

Your wsdl file is an xml based protocol for data exchange that defines how to access a remote web service. Call your wsdl file bmicalculator.wsdl

您的 wsdl 文件是一个基于 xml 的数据交换协议,它定义了如何访问远程 Web 服务。调用您的 wsdl 文件bmicalculator.wsdl

<definitions name="HelloService" targetNamespace="http://www.examples.com/wsdl/HelloService.wsdl" 
  xmlns="http://schemas.xmlsoap.org/wsdl/" 
  xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" 
  xmlns:tns="http://www.examples.com/wsdl/HelloService.wsdl" 
  xmlns:xsd="http://www.w3.org/2001/XMLSchema">

  <message name="getBMIRequest">
    <part name="weight" type="xsd:float"/>
    <part name="height" type="xsd:float"/>
  </message>

  <message name="getBMIResponse">
    <part name="bmi" type="xsd:float"/>
  </message>

  <portType name="Hello_PortType">
    <operation name="calculateBMI">
      <input message="tns:getBMIRequest"/>
      <output message="tns:getBMIResponse"/>
    </operation>
  </portType>

  <binding name="Hello_Binding" type="tns:Hello_PortType">
    <soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/>
    <operation name="calculateBMI">
      <soap:operation soapAction="calculateBMI"/>
      <input>
        <soap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="urn:examples:helloservice" use="encoded"/>
      </input>
      <output>
        <soap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="urn:examples:helloservice" use="encoded"/>
      </output>
    </operation>
  </binding>

  <service name="BMI_Service">
    <documentation>WSDL File for HelloService</documentation>
    <port binding="tns:Hello_Binding" name="BMI_Port">
      <soap:address location="http://localhost:3030/bmicalculator/" />
    </port>
  </service>
</definitions>

Hope it helps

希望能帮助到你

回答by Halfstop

The simplest way I found to just send raw XML to a SOAP service using Node.js is to use the Node.js http implementation. It looks like this.

我发现使用 Node.js 将原始 XML 发送到 SOAP 服务的最简单方法是使用 Node.js http 实现。它看起来像这样。

var http = require('http');
var http_options = {
  hostname: 'localhost',
  port: 80,
  path: '/LocationOfSOAPServer/',
  method: 'POST',
  headers: {
    'Content-Type': 'application/x-www-form-urlencoded',
    'Content-Length': xml.length
  }
}

var req = http.request(http_options, (res) => {
  console.log(`STATUS: ${res.statusCode}`);
  console.log(`HEADERS: ${JSON.stringify(res.headers)}`);
  res.setEncoding('utf8');
  res.on('data', (chunk) => {
    console.log(`BODY: ${chunk}`);
  });

  res.on('end', () => {
    console.log('No more data in response.')
  })
});

req.on('error', (e) => {
  console.log(`problem with request: ${e.message}`);
});

// write data to request body
req.write(xml); // xml would have been set somewhere to a complete xml document in the form of a string
req.end();

You would have defined the xml variable as the raw xml in the form of a string.

您可以将 xml 变量定义为字符串形式的原始 xml。

But if you just want to interact with a SOAP service via Node.js and make regular SOAP calls, as opposed to sending raw xml, use one of the Node.js libraries. I like node-soap.

但是,如果您只想通过 Node.js 与 SOAP 服务交互并进行常规 SOAP 调用,而不是发送原始 xml,请使用 Node.js 库之一。我喜欢node-soap

回答by dam1

Depending on the number of endpoints you need it may be easier to do it manually.

根据您需要的端点数量,手动执行可能更容易。

I have tried 10 libraries "soap nodejs" I finally do it manually.

我已经尝试了 10 个库“soap nodejs”,我终于手动完成了。

回答by smentek

I successfully used "soap" package (https://www.npmjs.com/package/soap) on more than 10 tracking WebApis (Tradetracker, Bbelboon, Affilinet, Webgains, ...).

我成功地在 10 多个跟踪 WebApis(Tradetracker、Bbelboon、Affilinet、Webgains 等)上使用了“soap”包(https://www.npmjs.com/package/soap)。

Problems usually come from the fact that programmers does not investigate to much about what remote API needs in order to connect or authenticate.

问题通常来自这样一个事实,即程序员没有过多调查远程 API 需要什么才能连接或验证。

For instance PHP resends cookies from HTTP headers automatically, but when using 'node' package, it have to be explicitly set (for instance by 'soap-cookie' package)...

例如,PHP 会自动从 HTTP 标头重新发送 cookie,但是在使用“node”包时,必须明确设置(例如通过“soap-cookie”包)...

回答by Vince Lowe

I used the node net module to open a socket to the webservice.

我使用 node net 模块打开一个到 webservice 的套接字。

/* on Login request */
socket.on('login', function(credentials /* {username} {password} */){   
    if( !_this.netConnected ){
        _this.net.connect(8081, '127.0.0.1', function() {
            logger.gps('('+socket.id + ') '+credentials.username+' connected to: 127.0.0.1:8081');
            _this.netConnected = true;
            _this.username = credentials.username;
            _this.password = credentials.password;
            _this.m_RequestId = 1;
            /* make SOAP Login request */
            soapGps('', _this, 'login', credentials.username);              
        });         
    } else {
        /* make SOAP Login request */
        _this.m_RequestId = _this.m_RequestId +1;
        soapGps('', _this, 'login', credentials.username);          
    }
});

Send soap requests

发送肥皂请求

/* SOAP request func */
module.exports = function soapGps(xmlResponse, client, header, data) {
    /* send Login request */
    if(header == 'login'){
        var SOAP_Headers =  "POST /soap/gps/login HTTP/1.1\r\nHost: soap.example.com\r\nUser-Agent: SOAP-client/SecurityCenter3.0\r\n" +
                            "Content-Type: application/soap+xml; charset=\"utf-8\"";        
        var SOAP_Envelope=  "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" +
                            "<env:Envelope xmlns:env=\"http://www.w3.org/2003/05/soap-envelope\" xmlns:SOAP-ENC=\"http://www.w3.org/2003/05/soap-encoding\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:n=\"http://www.example.com\"><env:Header><n:Request>" +
                            "Login" +
                            "</n:Request></env:Header><env:Body>" +
                            "<n:RequestLogin xmlns:n=\"http://www.example.com.com/gps/soap\">" +
                            "<n:Name>"+data+"</n:Name>" +
                            "<n:OrgID>0</n:OrgID>" +                                        
                            "<n:LoginEntityType>admin</n:LoginEntityType>" +
                            "<n:AuthType>simple</n:AuthType>" +
                            "</n:RequestLogin></env:Body></env:Envelope>";

        client.net.write(SOAP_Headers + "\r\nContent-Length:" + SOAP_Envelope.length.toString() + "\r\n\r\n");
        client.net.write(SOAP_Envelope);
        return;
    }

Parse soap response, i used module - xml2js

解析肥皂响应,我使用了模块 - xml2js

var parser = new xml2js.Parser({
    normalize: true,
    trim: true,
    explicitArray: false
});
//client.net.setEncoding('utf8');

client.net.on('data', function(response) {
    parser.parseString(response);
});

parser.addListener('end', function( xmlResponse ) {
    var response = xmlResponse['env:Envelope']['env:Header']['n:Response']._;
    /* handle Login response */
    if (response == 'Login'){
        /* make SOAP LoginContinue request */
        soapGps(xmlResponse, client, '');
    }
    /* handle LoginContinue response */
    if (response == 'LoginContinue') {
        if(xmlResponse['env:Envelope']['env:Body']['n:ResponseLoginContinue']['n:ErrCode'] == "ok") {           
            var nTimeMsecServer = xmlResponse['env:Envelope']['env:Body']['n:ResponseLoginContinue']['n:CurrentTime'];
            var nTimeMsecOur = new Date().getTime();
        } else {
            /* Unsuccessful login */
            io.to(client.id).emit('Error', "invalid login");
            client.net.destroy();
        }
    }
});

Hope it helps someone

希望它可以帮助某人

回答by euroblaze

You may also look at the easysoap npm - https://www.npmjs.org/package/easysoap-or- some of these: https://nodejsmodules.org/tags/soap

您还可以查看 easysoap npm - https://www.npmjs.org/package/easysoap- 或其中一些:https: //nodejsmodules.org/tags/soap

https://nodejsmodules.org/pkg/express-soap2json

https://nodejsmodules.org/pkg/express-soap2json

回答by J.Aliaga

Adding to Kim .J's solution: you can add preserveWhitespace=truein order to avoid a Whitespace error. Like this:

添加到Kim .J 的解决方案:您可以添加preserveWhitespace=true以避免出现空白错误。像这样:

soap.CreateClient(url,preserveWhitespace=true,function(...){