无法通过公司代理进行 HTTPS SOAP 调用 - getaddrinfo ENOTFOUND

Can't make HTTPS SOAP call through corporate proxy - getaddrinfo ENOTFOUND

我正在尝试通过 HTTPS 进行 SOAP 调用。通常我在 Azure 中执行此操作,效果很好,但我正在开发一个新模块,需要通过我们的公司代理在本地调用它。如果我只是正常拨打电话,我会收到一条 SELF_SIGNED_CERTIFICATE_IN_CHAIN 错误消息。在某些情况下,我可以使用 https-proxy-agent 模块来解决这个问题,但是当我如下设置它时,我收到错误消息 getaddrinfo ENOTFOUND undefined undefined:80。我确定代理 URL 有效。当我调试调用时,我可以看到传递给调用的代理信息(通过 easy-soap-request 启动 SOAP 调用,然后通过 axios 进行 http 调用)。以下是一些相关的代码片段:

const soapRequest = require('easy-soap-request');
let httpsProxyAgent = require('https-proxy-agent');
var agent = new httpsProxyAgent({hostname:'proxy.address.com', port:8080, rejectUnauthorized:false});

// Next lines are within the class of my helper function

await (async () => {
            var response = {};
            try {
                console.log('Converting catalog number...');
                console.log(url);
                response = await soapRequest(url, headers, requestXML, 10000, {httpsAgent:agent});

            } catch (err) {
                console.log(`Error converting catalog number: ${err}`);
                processObj.message = 'SERVICE_DOWN';
                processObj.error = err.message;
                return;
            }

// Then do some more stuff with the response, but I don't get this far

easy-soap-request 模块本身似乎并没有做太多事情。让我想知道为什么我不只是用 request-promise-native 做一个 post (我将它用于所有其他 API 调用),但我想这不是重点。这里有easy-soap-request模块供参考。我唯一注意到的是它实际上使用 axios-https-proxy-fix 而不是 axios

const axios = require('axios-https-proxy-fix');

module.exports = function soapRequest(url, headers, xml, timeout = 10000, proxy = false) {
  return new Promise((resolve, reject) => {
    axios({
      method: 'post',
      url,
      headers,
      data: xml,
      timeout,
      proxy,
    }).then((response) => {
      resolve({
        response: {
          headers: response.headers,
          body: response.data,
          statusCode: response.status,
        },
      });
    }).catch((error) => {
      if (error.response) {
        console.error(`SOAP FAIL: ${error}`);
        reject(error.response.data);
      } else {
        console.error(`SOAP FAIL: ${error}`);
        reject(error);
      }
    });
  });
};

看来我关于 easy-soap-request 并没有真正增加多少价值的评论被证明是正确的。我可以轻松地使用 request-promise-native 作为替代品。因为后者尊重我的 .env 代理变量,所以我也不需要使用 httpsAgent。我仍然必须在选项中添加 rejectUnauthorized:false 。这是更新后的代码,原始行被注释掉了:

//const soapRequest = require('easy-soap-request');
//let httpsProxyAgent = require('https-proxy-agent');
//var agent = new httpsProxyAgent({hostname:'proxy.address.com', port:8080, rejectUnauthorized:false});
const request = require('request-promise-native');

// Next lines are within the class of my helper function

await (async () => {
            var response = {};
            try {
                console.log('Converting catalog number...');
                console.log(url);
                //response = await soapRequest(url, headers, requestXML, 10000, {httpsAgent:agent});
                response = await request({
                    url: url,
                    method: 'POST',
                    headers: headers,
                    body: requestXML,
                    rejectUnauthorized: false
                })

            } catch (err) {
                console.log(`Error converting catalog number: ${err}`);
                processObj.message = 'SERVICE_DOWN';
                processObj.error = err.message;
                return;
            }

工作起来很有魅力!我实际上要回去更新我的其他集成模块以在整个应用程序中使用此方法而不是 easy-soap-request

使用4.1.3版本测试成功。 您以错误的方式向 Axios 发送参数

替换:

let httpsProxyAgent = require('https-proxy-agent');
var agent = new httpsProxyAgent({hostname:<>, port:<>, rejectUnauthorized:false});

有: var proxy = {host:<>, port:<>};

和: const { response } = await soapRequest({ url: url, headers: sampleHeaders, xml: xml, timeout: 1000000, proxy: {httpsAgent: agent }});

const { response } = await soapRequest({ url: url, headers: sampleHeaders, xml: xml, timeout: 1000000, proxy});

应该更新库的文档,因为它没有显示使用代理的方法。

在您提出问题时: 有一个与 Axios 代理不工作相关的问题,但在您提出问题前一年已关闭: https://github.com/axios/axios/issues/2072#

当时建议使用 proxyagent 作为一种解决方法,请在此处查看一个答案:

考虑到该答案,您必须在 proxyAgent 定义中将 'hostname' 替换为 'host' 才能使您的代码正常工作。