[axios]ERR_CONNECTION_REFUSED 与 ERR_INTERNET_DISCONNECTED 的判断

2024-08-22 574 views
3
概括

Axios 是否应区分以下内容:

  • 由于客户端在发出请求时没有网络连接而导致请求失败 - (ERR_CONNECTION_REFUSED)。
  • 由于在发出请求之后但在收到响应之前丢失网络连接而导致请求失败- (ERR_INTERNET_DISCONNECTED)。

似乎在这两种情况下,我们得到的只是一条毫无帮助的“网络错误”消息……

文档 ( https://github.com/axios/axios#handling-errors ) 建议在后一种情况下,error.request应该填充,但我无法复制存在的任何场景error.request。在上述两种情况下,我都会得到一个如下所示的错误对象:

{
  config: { ... },
  response: undefined,
  message: "Network Error",
  stack: "Error: Network Error at createError (http://localhost:3000/static/js/bundle.js:1636:15) at XMLHttpRequest.handleError (http://localhost:3000/static/js/bundle.js:1170:14)"
}
语境
  • axios版本:v0.17.1

回答

4

您是在节点还是在浏览器中使用 axios?

如果我这样做,没有互联网,axios.get(' https://404/foo').catch(error => console.log(error.request)); 在浏览器中我得到一个XMLHttpRequest。

看起来我也用同样的代码在节点中得到了正确的东西。

您有可以重现该问题的代码吗?

2

为了尝试模拟这个问题,我编写了一个基本的 Node API:

var express = require('express');
var app = express();

app.get('/', function (req, res) {
  setTimeout(() => {
    res.send('Finished');
  }, 10000);
});

app.listen(8282, function () {
  console.log('Node API listening on port 8282...')
});

以及一个简单的 Node 客户端:

var express = require('express');
var app = express();
var axios = require('axios');

app.get('/', function (req, res) {
  const config = {
    url: 'http://localhost:8282',
    method: 'GET',
    timeout: 30000,
  };
  axios(config)
  .then((response) => {
    res.status(200).send(response.data);
  })
  .catch((error) => {
    res.status(500).send({
      code: error.code,
      config: error.config,
      response: error.response,
    });
  });
});

app.listen(8181, function () {
  console.log('Node client listening on port 8181...')
});

从命令行启动两个应用程序,浏览到http://localhost:8181,然后终止 API 应用程序以模拟连接断开,客户端收到以下错误详细信息:

{
  "code": "ECONNRESET",
  "config": {
    "transformRequest": {},
    "transformResponse": {},
    "timeout": 30000,
    "xsrfCookieName": "XSRF-TOKEN",
    "xsrfHeaderName": "X-XSRF-TOKEN",
    "maxContentLength": -1,
    "headers": {
      "Accept": "application/json, text/plain, */*",
      "User-Agent": "axios/0.18.0"
    },
    "method": "get",
    "url":"http://localhost:8282"
  }
}

因此,答案可能是查看错误代码 - 在本例中为 ECONNRESET。(请注意,如果请求超时,您将收到 ECONNABORTED 错误代码。)

3

这个问题解决了吗?发生此错误后,我的应用程序一直无法使用。这是一个 React 应用程序,它通过 react-on-rails 连接到 Rails 应用程序。发生这种情况后,让应用程序重新运行的唯一方法是刷新。

2

仍然有同样的问题,请问有什么解决办法

9

+1。

我需要区分这两种情况:

POST https://xxx.com/sendMessage net::ERR_NAME_NOT_RESOLVED POST https://xxx.com/sendMessage net::ERR_INTERNET_DISCONNECTED

据我检查,上述两种情况下,catch 块返回的错误是相同的。

最少的重现步骤:打开浏览器控制台,运行:

axios({
    method: 'GET',
    url: `https://api.URL_NOT_EXIST.org/sendMessage`,
  }).then(console.log).catch(function(error) {
  console.dir(error);
  console.log('error.status: ', error.status)
  if (!error.status) {
    // network error
    console.log('network error')
  }
});

断开互联网,再次运行上述请求

0

有什么更新吗?

5

我也在寻找解决方案,根据这篇文章https://bugs.chromium.org/p/chromium/issues/detail?id=118096#c5的说法,这不会那么容易。我想到的唯一想法是在最终获取之前请求外部 DNS 服务,这可能会解决这两个问题,因此当 DNS 响应时,我们可以从响应中识别出名称是否正确,否则 net::ERR_NAME_NOT_RESOLVED 当 DNS 超时时,很有可能 net::ERR_INTERNET_DISCONNECTED 这将需要信任公共 DNS 的 CORS,或者我们可能需要设置后端端点来检查该内容,例如 https://dns.google/query?name=localhost 和 json api https://dns.google/resolve?name=localhost&type=A