如何将这段 PHP SoapClient 代码翻译成使用 node-soap 的 node.js 代码?

huangapple go评论119阅读模式
英文:

How do I translate this PHP SoapClient code into node.js using node-soap?

问题

以下是您要翻译的内容:

"I seem to be able to create a Soap Client but when I call the Soap function "PersonSok" it throws me that error: connect ECONNREFUSED ::1:80. I use express to start the node.js project. Here is my code so far: (the two functions and only a part of the whole code)"

  1. // 发送请求
  2. export function sendRequest() {
  3. return new Promise((resolve, reject) => {
  4. var args = { "Identifieringsinformation": createIdentifieringsInformation()};
  5. args["PersonsokningFraga"] = {"IdNummer": 195704133106};
  6. console.log("Passing arguments to PersonSok: " + args);
  7. // 创建SOAP客户端
  8. createSoapClient().then((client) => {
  9. client.PersonSok(args, function (err, result) {
  10. if(err) {
  11. reject(err);
  12. } else {
  13. resolve(result);
  14. }
  15. });
  16. });
  17. });
  18. }
  19. // 创建SOAP客户端
  20. export function createSoapClient() {
  21. return new Promise(async (resolve, reject) => {
  22. var url = './assets/personsok.wsdl';
  23. // 下面的注释掉的代码是我尝试过的一些方法,但仍然出现相同的错误。
  24. /*
  25. const secureContext = tls.createSecureContext({
  26. cert: fs.readFileSync('assets/Kommun_A.pem'),
  27. ca: fs.readFileSync('assets/DigiCert.pem'),
  28. });
  29. */
  30. //var client = await soap.createClientAsync(url, { secureContext, secureOptions: tls.SSL_OP_NO_TLSv1_2, rejectUnauthorized: false });
  31. var client = await soap.createClientAsync(url, { rejectUnauthorized: false, strictSSl: false, secureOptions: tls.SSL_OP_NO_TLSv1_2 });
  32. var wssec = new soap.ClientSSLSecurity('assets/private-key.pem', 'assets/csr.pem', 'assets/public-cert.pem');
  33. client.setSecurity(wssec);
  34. if(!client) {
  35. reject("Error: could not create SOAP client.");
  36. }
  37. console.log("Created SOAP Client");
  38. resolve(client);
  39. });
  40. }

希望这可以帮助您解决问题!

英文:

I am completely new to SOAP Api's and have an API that only accepts SOAP requests. The documentation is very bad to non-existent, but they do have some example implementations showing everything of in PHP, Java and .Net. I am able to understand the PHP code slightly and My goal is and I have tried to translate it to JS with "soap", but I just get the error: connect ECONNREFUSED ::1:80. The API requires the use of certificates and needs TLS 1.2 handshaking.

Here is the code snippit in PHP, that I want to translate into Node.js with node-soap:

  1. function createSoapClient()
  2. {
  3. $sslOptions = array(
  4. 'local_cert' => $_POST['certifikat'],
  5. 'verify_peer' => true,
  6. 'cafile' => $_POST['ca'],
  7. 'CN_match' => 'kt-ext-portwise.statenspersonadressregister.se');
  8. $streamcontext = stream_context_create(
  9. array('ssl' => $sslOptions));
  10. $options = array(
  11. 'location' => $_POST['url'],
  12. 'stream_context' => $streamcontext);
  13. // For the client to be able to read the file locally it requires a "file:// in front of the path"
  14. $wsdl = 'file://' . dirname(__FILE__) . DIRECTORY_SEPARATOR . 'resurser/personsok-2021.1.wsdl';
  15. return new SoapClient($wsdl, $options);
  16. }

I seem to be able to create a Soap Client but when I call the Soap function "PersonSok" it throws me that error: connect ECONNREFUSED ::1:80. I use express to start the node.js project. Here is my code so far: (the two functions and only a part of the whole code)

  1. // Send request
  2. export function sendRequest() {
  3. return new Promise((resolve, reject) => {
  4. var args = { "Identifieringsinformation": createIdentifieringsInformation()};
  5. args["PersonsokningFraga"] = {"IdNummer": 195704133106};
  6. console.log("Passing arguments to PersonSok: " + args);
  7. // Create soap client
  8. createSoapClient().then((client) => {
  9. client.PersonSok(args, function (err, result) {
  10. if(err) {
  11. reject(err);
  12. } else {
  13. resolve(result);
  14. }
  15. });
  16. });
  17. });
  18. }
  19. // Create SOAP Client
  20. export function createSoapClient() {
  21. return new Promise(async (resolve, reject) => {
  22. var url = './assets/personsok.wsdl';
  23. // The commented code below is just some methods I have tried, but still same error.
  24. /*
  25. const secureContext = tls.createSecureContext({
  26. cert: fs.readFileSync('assets/Kommun_A.pem'),
  27. ca: fs.readFileSync('assets/DigiCert.pem'),
  28. });
  29. */
  30. //var client = await soap.createClientAsync(url, { secureContext, secureOptions: tls.SSL_OP_NO_TLSv1_2, rejectUnauthorized: false });
  31. var client = await soap.createClientAsync(url, { rejectUnauthorized: false, strictSSl: false, secureOptions: tls.SSL_OP_NO_TLSv1_2 });
  32. var wssec = new soap.ClientSSLSecurity('assets/private-key.pem', 'assets/csr.pem', 'assets/public-cert.pem');
  33. client.setSecurity(wssec);
  34. if(!client) {
  35. reject("Error: could not create SOAP client.");
  36. }
  37. console.log("Created SOAP Client");
  38. resolve(client);
  39. });
  40. }

I appreciate all the help I can get! :)))

答案1

得分: 0

我最终找到了一个可用的翻译。 在这种情况下,我正在尝试向瑞典 SPAR API(Statens personadressregister)发送请求,因此可能与您正在尝试访问的 API 之间存在差异。

但是在路上,我遇到了连续三个错误,以下是我如何修复它们:

错误1: "ECONNECTREFUSED ::1:80"
错误1的解决方法:在我的先前的测试代码中,我没有设置请求应该发送到的端点,就像 PHP 选项中的“location”对应于 client.setEndpoint(url) 一样。我无法真正解释这一点,但是 这个线程 在创建的 SOAP 客户端的 wsdl_options 中设置了证书和密钥选项,包括 client.ClientSSLSecurity() 和一个新的覆盖 HttpAgent

错误2: "ECONNECT socket hangup"
错误2的解决方法:我注意到,我的先前的 SOAP 请求具有默认的“connection”头部为“close”。我认为,由于某种原因,连接在任何响应完成之前关闭了。因此,解决方法是添加以下代码: client.addHttpHeader("connection", "keep-alive")。我还在 Stack Overflow 上看到其他人遇到类似错误时也采用了这个解决方法。

在这个阶段,我能够在我的客户端和 SPAR 的 API 之间建立连接和成功的验证。

错误3:验证错误
错误3的解决方法:这更多地与我尝试访问的 API 相关的特定错误,但也可能成为您的问题。我意识到,我的参数必须按正确的顺序排列,否则会引发(在我的情况下)验证错误。查看您的 wsdl 以获取更多信息!例如,以下方式对我不起作用:

  1. const args = {
  2. arg2: blabla,
  3. arg1: blabaa,
  4. ...
  5. }

最后但并非最不重要的,这是整个代码。填写您需要进行请求的信息。这个代码对我有效,我只有大约40个小时的 SOAP 经验,所以不要完全依赖我的话。我只是尽力用我所知道的最好的方式来解释 如何将这段 PHP SoapClient 代码翻译成使用 node-soap 的 node.js 代码?

  1. // 代码在这里

如果您有任何问题、建议或对此事的更好解释,请向我提问。

英文:

I finally found a working translation. In this case I am trying to post a request to the Swedish SPAR API (Statens personadressregister) so there could be differences between this and the API your are trying to reach.

But on the road I got confronted with three errors after each other, here is how I fixed them:

Error 1: "ECONNECTREFUSED ::1:80"
Solution to error 1: In my previous test code I didn't set an endpoint to where the request should go as there is in the PHP option "location" corresponding to client.setEndpoint(url). I can't really explain this, but this thread set the cert and key option in both the client.ClientSSLSecurity() and in a new and overriden HttpAgent inside of the wsdl_options of the created SOAP client.

Error 2: "ECONNECT socket hangup"
Solution to error 2: I saw, that my previous SOAP request had a default header of "connection": "close". I suppose, that the connection for some reason close before any response could be finished. The solution was therefore to add the code: client.addHttpHeader("connection", "keep-alive"). I also saw this solution for others on stack overflow having a similar error.

In this stage I was able to establish a connection and a successful auth between my client and SPAR's API.

Error 3: Validation error
Solution to error 3: So this is more of a specific error relating to the API I was trying to reach, but might also become a problem of your's. I realised, that my arguments has to be in a correct order of the object, otherwise it will throw (in my case) a validation error. Check your wsdl for more information on this!
For example this didn't work for me:

  1. const args = {
  2. arg2: blabla,
  3. arg1: blabaa,
  4. ...
  5. }

Last but not least, here is the entire code. Fill in the information, that you need to make your request. This one worked ME and I am just around 40 intensive hours experienced with SOAP so far, so don't take my word for everything. I just tried explain with the best of my knowledge 如何将这段 PHP SoapClient 代码翻译成使用 node-soap 的 node.js 代码?

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-js -->

  1. const soap = require(&#39;soap&#39;);
  2. const tls = require(&#39;tls&#39;);
  3. const fs = require(&#39;fs&#39;);
  4. const https = require(&#39;https&#39;);
  5. const express = require(&#39;express&#39;);
  6. const app = express();
  7. const port = 8080;
  8. const wsdlUrl = &quot;url&quot;;
  9. const endpoint = &quot;url&quot;;
  10. const cert = &quot;pathToCert&quot;;
  11. const key = &quot;pathToKey&quot;;
  12. const args = {
  13. {yourArgs}
  14. };
  15. // Create Client
  16. async function createClient() {
  17. var sec = new soap.ClientSSLSecurity(
  18. key, // key
  19. cert, // cert
  20. );
  21. var client = await soap.createClientAsync(wsdlUrl, {
  22. wsdl_options: {
  23. httpsAgent: new https.Agent({
  24. key: fs.readFileSync(key),
  25. cert: fs.readFileSync(cert),
  26. }),
  27. },
  28. });
  29. client.addHttpHeader(&#39;connection&#39;, &#39;keep-alive&#39;);
  30. client.setEndpoint(endpoint);
  31. client.setSecurity(sec);
  32. return client;
  33. }
  34. // Send soap request with custom arguments
  35. async function sendSOAPRequest(args) {
  36. var client = await createClient();
  37. var result = await client.MyFunction(args);
  38. return result;
  39. }
  40. app.get(&#39;/&#39;, (req, res) =&gt; {
  41. res.send(&quot;Node-SOAP test.&quot;);
  42. });
  43. app.get(&#39;/yourNodeJSEndpoint&#39;, async (req, res) =&gt; {
  44. var result = await sendSOAPRequest(args);
  45. res.send(result);
  46. });
  47. app.listen(port, () =&gt; {
  48. console.log(`Example app listening on port ${port}`);
  49. });

<!-- end snippet -->

Ask me if you have any questions, suggestions or better explanations on this matter.

huangapple
  • 本文由 发表于 2023年1月8日 18:53:07
  • 转载请务必保留本文链接:https://go.coder-hub.com/75047191.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定