Javascript: проверить, подключен ли сервер к сети?

Какой самый быстрый способ проверить, подключен ли мой сервер к сети через JavaScript?

Я пробовал следующий AJAX:

function isonline() {
    var uri = 'MYURL'
    var xhr = new XMLHttpRequest();
    xhr.open("GET",uri,false);
    xhr.send(null);
    if(xhr.status == 200) {
        //is online
        return xhr.responseText;
    }
    else {
        //is offline
        return null;
    }   
}

Проблема в том, что он никогда не возвращается, если сервер находится в автономном режиме. Как я могу установить тайм-аут, чтобы, если он не вернулся через определенное время, я мог предположить, что он не в сети?

7 ответов

Решение

XMLHttpRequest не работает междоменный. Вместо этого я бы загрузить крошечный <img> что вы ожидаете вернуться быстро и посмотреть onload событие:

function checkServerStatus()
{
    setServerStatus("unknown");
    var img = document.body.appendChild(document.createElement("img"));
    img.onload = function()
    {
        setServerStatus("online");
    };
    img.onerror = function()
    {
        setServerStatus("offline");
    };
    img.src = "http://myserver.com/ping.gif";
}

Изменить: Очистка мой ответ. XMLHttpRequest Решение возможно в том же домене, но если вы просто хотите проверить, подключен ли сервер, решение img load является самым простым. Нет необходимости связываться с таймаутами. Если вы хотите, чтобы код выглядел синхронно, вот вам синтаксический сахар:

function ifServerOnline(ifOnline, ifOffline)
{
    var img = document.body.appendChild(document.createElement("img"));
    img.onload = function()
    {
        ifOnline && ifOnline.constructor == Function && ifOnline();
    };
    img.onerror = function()
    {
        ifOffline && ifOffline.constructor == Function && ifOffline();
    };
    img.src = "http://myserver.com/ping.gif";        
}

ifServerOnline(function()
{
    //  server online code here
},
function ()
{
    //  server offline code here
});

Вот как я добился проверки доступности сервера с помощью Fetch для управления запросом и AbortController для обработки тайм-аута в приложении Node.js.

function checkServer(url, timeout) {
  const controller = new AbortController();
  const signal = controller.signal;
  const options = { mode: 'no-cors', signal };
  return fetch(url, options)
    .then(setTimeout(() => { controller.abort() }, timeout))
    .then(response => console.log('Check server response:', response.statusText))
    .catch(error => console.error('Check server error:', error.message));
}

Добавить в ответ gilly3

На практике я обнаружил необходимость использовать document.body.appendChild довольно медленно.

Хотя речь идет о чистом JavaScript, использование некоторого HTML сделает это решение намного быстрее.

Так что я оставляю этот код здесь для всех, кому нужна скорость.

<html>
<head>
    <title>Some page</title>
</head>

<body>
  <img src="https://myserver.com/ping.gif"  onload="pageOnline()" onerror="pageOffline()">

  <script>


  function pageOnline() {
    // Online code
  }

  function pageOffline() {
    // Offline code
  }
</script>
</body>
</html>

Первоначальные ответы все еще действительны, но довольно устарели. Вот мой подход:

      import axios from 'axios'
import to from 'await-to-js'

export default async function pingAppReady(healthCheckPath: string, recursive = true) {
  return new Promise<void>(async (resolve, reject) => {
    // Ping the path e.g http://localhost:3000
    const [err] = await to(axios.get(healthCheckPath))

    // resolve if the ping returns no error or error that is not related to the connection
    if (!err) return resolve()
    if (err.code !== 'ECONNREFUSED') return resolve()

    if (!recursive) reject()

    setTimeout(async () => {
      await pingAppReady(healthCheckPath, recursive)
      resolve()
    }, 5000)
  })
}

Используйте XMLHttpRequestЗатем проверьте, не удалось ли это. Не уверен, что это будет работать кросс-домен, хотя.

СXMLHttpRequestне работал для меня дляcorsпроблемы, я нашел и попробовал ответ gilly3, и он отлично работает, если вы позвоните ему один раз. Это не удается, когда вы часто проверяете сервер, так как загруженный графический файл уже находится в кеше браузера. Поэтому я добавил случайный элемент в качестве строки запроса, чтобы избежать этого. (Решение, которое я также нашел где-то при переполнении стека.)

      function checkServer(callback, fqdn, imagepath="/favicon.ico") {
    let img = new Image();
    img.onload = function() { callback(fqdn, true); };
    img.onerror = function() { callback(fqdn, false); };
    img.src = "http://" + fqdn + imagepath + '?r=' + Math.random(); /* avoids caching */
}

Сделайте вызов ajax и его результат скажет.

Другие вопросы по тегам