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 */
}