我如何将这个PHP SoapClient代码转换为使用node-soap的node.js ?



我对SOAP Api完全陌生,并且有一个只接受SOAP请求的Api。文档非常糟糕,甚至不存在,但他们确实有一些示例实现,展示了PHP, Java和。net中的所有内容。我能够稍微理解PHP代码,我的目标是,我试图将其翻译成JS与quot;皂"但我只是得到错误:connect ECONNREFUSED ::1:80。该API需要使用证书,并且需要TLS 1.2握手。

这是PHP中的代码片段,我想用node-soap转换成Node.js:

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

我似乎能够创建一个Soap客户端,但当我调用Soap函数"PersonSok"它给我的错误是:connect ECONNREFUSED ::1:80。我使用express来启动node.js项目。以下是我到目前为止的代码:(两个函数,只是整个代码的一部分)

// Send request
export function sendRequest() {
return new Promise((resolve, reject) => {
var args = { "Identifieringsinformation": createIdentifieringsInformation()};
args["PersonsokningFraga"] = {"IdNummer": 195704133106};
console.log("Passing arguments to PersonSok: " + args);

// Create soap client
createSoapClient().then((client) => {
client.PersonSok(args, function (err, result) {
if(err) {
reject(err);
} else {
resolve(result);
}
});
});
});
}
// Create SOAP Client
export function createSoapClient() {
return new Promise(async (resolve, reject) => {
var url = './assets/personsok.wsdl';
// The commented code below is just some methods I have tried, but still same error.
/*
const secureContext = tls.createSecureContext({
cert: fs.readFileSync('assets/Kommun_A.pem'),
ca: fs.readFileSync('assets/DigiCert.pem'),
});
*/
//var client = await soap.createClientAsync(url, { secureContext, secureOptions: tls.SSL_OP_NO_TLSv1_2, rejectUnauthorized: false });
var client = await soap.createClientAsync(url, { rejectUnauthorized: false, strictSSl: false, secureOptions: tls.SSL_OP_NO_TLSv1_2 });
var wssec = new soap.ClientSSLSecurity('assets/private-key.pem', 'assets/csr.pem', 'assets/public-cert.pem');
client.setSecurity(wssec);
if(!client) {
reject("Error: could not create SOAP client.");
}
console.log("Created SOAP Client");
resolve(client);
});
}

我很感激我能得到的所有帮助!:)))

我终于找到了一个可行的翻译在这种情况下,我正试图向瑞典SPAR API (Statens personaddressregister)发布请求,因此这与您试图达到的API之间可能存在差异。

但是在路上我接连遇到了三个错误,这里是我如何修复它们的:

错误1:ECONNECTREFUSED::1:80">错误1的解决方案:在我之前的测试代码中,我没有像PHP选项"location"那样设置一个端点到请求应该去的地方。对应client.setEndpoint(url)。我不能真正解释这一点,但是这个线程在client.ClientSSLSecurity()和创建的SOAP客户机的wsdl_options内部的一个新的和覆盖的HttpAgent中设置了证书和密钥选项。

错误2:ECONNECT socket hangup&;错误2的解决方案:我看到,我以前的SOAP请求有一个默认的标头&;connection&;; &;close&;。我猜想,由于某种原因,连接在任何响应完成之前就关闭了。因此,解决方案是添加代码:client.addHttpHeader("connection", "keep-alive")。我也看到这个解决方案的其他堆栈溢出有类似的错误。

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

错误3:验证错误错误3的解决方案:因此,这是一个与我试图达到的API相关的特定错误,但也可能成为您的问题。我意识到,我的参数必须以对象的正确顺序排列,否则它将抛出(在我的情况下)验证错误。请检查您的wsdl以获得有关此的更多信息!例如:

const args = {
arg2: blabla,
arg1: blabaa,
...
}

最后但并非最不重要的是,这里是整个代码。填上你提出请求所需的信息。这个方法对我很有效,到目前为止,我只有大约40个小时密集的SOAP经验,所以不要相信我的话。我只是尽我所能解释一下:)

const soap = require('soap');
const tls = require('tls');
const fs = require('fs');
const https = require('https');
const express = require('express');
const app = express();
const port = 8080;
const wsdlUrl = "url";
const endpoint = "url";
const cert = "pathToCert";
const key = "pathToKey";
const args = { 
{yourArgs}
};
// Create Client
async function createClient() {
var sec = new soap.ClientSSLSecurity(
key, // key
cert, // cert
);
var client = await soap.createClientAsync(wsdlUrl, { 
wsdl_options: {
httpsAgent: new https.Agent({
key: fs.readFileSync(key),
cert: fs.readFileSync(cert),
}),
},
});
client.addHttpHeader('connection', 'keep-alive');
client.setEndpoint(endpoint);
client.setSecurity(sec);

return client;
}
// Send soap request with custom arguments
async function sendSOAPRequest(args) {
var client = await createClient();
var result = await client.MyFunction(args);
return result;
}


app.get('/', (req, res) => {
res.send("Node-SOAP test.");
});
app.get('/yourNodeJSEndpoint', async (req, res) => {
var result = await sendSOAPRequest(args);
res.send(result);
});

app.listen(port, () => {
console.log(`Example app listening on port ${port}`);
});

如果你有任何问题,建议或更好的解释,请问我。

最新更新