0

Before you mark it as a duplicate, please read.

I am trying to simulate ping using javascript e.g. It should show status (Up/Down) for a given website.

www.google.com => Up
www.dummysite.com => down

I tried four approaches
1. Using AJAX (works only for the same origin server)
2. Using Image trick (works only if the remote server returns an image)
3. Using JSONP (Doesn't work as server returns an HTML page)
4. Using $.getScript (Works for all site except lorem pixel because its MIME type ('image/jpeg') is not executable.) Didn't quite understand how it's different than 3.

JSFiddle: CORS

var sites = {
  google: {
    url: "https://www.google.com",
    id: "googleStatus"
  },
  dummy: {
    url: "http://www.dummysitealphabeta2.com",
    id: "dummySiteStatus"
  },
  jsfiddle: {
    url: "https://fiddle.jshell.net",
    id: "jsfiddleStatus"
  },
  lorem: {
    url: "https://lorempixel.com/400/200/",
    id: "loremStatus"
  }
};

// Default
refreshAllSites('ajax');

function refreshAllSites(approach) {
  Object.keys(sites).forEach(function(name) {
    // Four approaches
    switch (approach) {
      case "ajax":
        // 1. Using AJAX (works only for the same origin)
        checkStatusUsingAJAX(sites[name]);
        break;

      case "image":
        // 2. Using Image trick (works only if 
        // the remote server returns image)
        checkStatusUsingImage(sites[name]);
        break;

      case "jsonp":
        // 3. Using JSONP (Doesn't work because server is an HTML page)
        checkStatusUsingJSONP(sites[name]);
        break;

      case "getscript":
        // 4. Using GetScript (Doesn't work for lorem pixel because its MIME type ('image/jpeg') is not executable.)
        checkStatusUsingGetScript(sites[name]);
        break;
    }
  });
}

// Approach 4: Using GetScript
function checkStatusUsingGetScript(site) {
  $.getScript(site.url + "?callback=?").done(function() {
    document.getElementById(site.id).innerHTML = "Up"
  }).fail(function() {
    document.getElementById(site.id).innerHTML = "Down"
  });
}

// Approach 3: Using JSONP
// Doesn't work as server returns an HTML page
function checkStatusUsingJSONP(site) {
  jsonp(site.url, function() {
    document.getElementById(site.id).innerHTML = "Up"
  }, function() {
    document.getElementById(site.id).innerHTML = "Down"
  });

  // Define JSONP
  function jsonp(url, success, fail) {
    var callbackName = 'jsonpCallback' +
      Math.round(10000 * Math.random());

    window[callbackName] = function(data) {
      console.log("calling callback");
      delete window[callbackName];
      document.body.removeChild(script);
      success(escape(data));
    }

    var script = document.createElement('script');
    script.src = url + "?callback=" + callbackName;
    script.onerror = fail;

    document.body.appendChild(script);
  }
}

// Approach 2: Using Image loading trick
// Only works if the remote server returns Image e.g. lorem pixel
// https://stackoverflow.com/a/5224638/351708
function checkStatusUsingImage(site) {
  var image = document.createElement("img");
  image.onload = function() {
    document.getElementById(site.id).innerHTML = "Up"
  };
  image.onerror = function() {
    document.getElementById(site.id).innerHTML = "Down"
  };

  image.src = site.url;
}


// Approach 1
// Using AJAX - It will only be successful in case of JSFiddle
// as for the rest of the sites it will throw CORS exception
function checkStatusUsingAJAX(site) {
  $.ajax(site.url).done(function() {
    document.getElementById(site.id).innerHTML = "Up"
  }).fail(function() {
    document.getElementById(site.id).innerHTML = "Down"
  });
};

// Other functions
var select = document.getElementById("approachOptions");
select.addEventListener("change", function(e) {
  refreshAllSites(this.value);
});
table {
  border-collapse: collapse;
  width: 100%;
}

td,
th {
  border-bottom: 1px solid black;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
Ping server using
<select id="approachOptions">
  <option value="ajax">AJAX</option>
  <option value="image">Image Trick</option>
  <option value="jsonp">JSONP</option>
  <option value="getscript">$.getScript()</option>
</select>
<table>
  <tr>
    <th>Website</th>
    <th>Status</th>
    <th>Uptime</th>
  </tr>
  <tr>
    <td>Google</td>
    <td>
      <label id="googleStatus"></label>
    </td>
    <td></td>
  </tr>
  <tr>
    <td>Dummy Site</td>
    <td>
      <label id="dummySiteStatus"></label>
    </td>
    <td></td>
  </tr>
  <tr>
    <td>JS Fiddle</td>
    <td>
      <label id="jsfiddleStatus"></label>
    </td>
    <td></td>
  </tr>
  <tr>
    <td>Lorem Pixel</td>
    <td>
      <label id="loremStatus"></label>
    </td>
    <td></td>
  </tr>
</table>

Similar questions:
Javascript: Check if server is online
Is it possible to ping a server from Javascript?
Use JSONP to load an html page
JavaScript XMLHttpRequest using JsonP

Community
  • 1
  • 1
Rohit
  • 5,328
  • 13
  • 53
  • 82

1 Answers1

0

Had the same problem, built a hacky solution:

http://ruthere.co/ https://github.com/glennzw/ruthere

Example:

var url = "https://stackoverflow.com";
var newImg = new Image;
newImg.src = "http://ruthere.co/u/" + url;
console.log("Checking " + url)

newImg.onload = function(){
    console.log(this.width);
    if (newImg.height == 200) {
        console.log("Stackoverflow is up!");
    } else {
        console.log("Stackoverflow broke :(");
    }
}
user1503941
  • 438
  • 3
  • 8