开发者

Javascript: Check if server is online?

What's the fastest way to check if my server is online via JavaScript?

I've tried the following 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;
    }   
}

The problem is, it never returns if the server is offline. How can 开发者_如何学PythonI set a timeout so that if it isn't returning after a certain amount of time, I can assume it is offline?


XMLHttpRequest does not work cross-domain. Instead, I'd load a tiny <img> that you expect to come back quickly and watch the onload event:

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";
}

Edit: Cleaning up my answer. An XMLHttpRequest solution is possible on the same domain, but if you just want to test to see if the server is online, the img load solution is simplest. There's no need to mess with timeouts. If you want to make the code look like it's synchronous, here's some syntactic sugar for you:

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
});


Here's how I achieved checking server availability using Fetch to manage the request and AbortController to handle a timeout within a Node.js application.

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));
}


Add to gilly3 answer

In practice, I found the need to use document.body.appendChild quite slow.

Although the question is about pure JavaScript, using some HTML will make that solution much faster.

So I am leaving this code here for anyone looking for speed.

<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>


Use an XMLHttpRequest, then check whether it failed. Not sure if this would work cross-domain though.


Make an ajax call and its result will tell.


The original answers are still valid, but quite outdated. Here is the approach I took:

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)
  })
}


Since XMLHttpRequest did not work for me for cors issues, I found and tried gilly3's answer and it works fine, if you call it once. It fails, when you check a server frequently, since the loaded graphics file is already in the cache of the browser. So I've added a random element as query string to avoid this. (A solution, I'v also found somewhere at stack overflow.)

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

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜