Skip to content

Instantly share code, notes, and snippets.

@gitdagray
Last active March 14, 2024 20:55
Show Gist options
  • Save gitdagray/f310be81be217750fc9d2b233e2ae70c to your computer and use it in GitHub Desktop.
Save gitdagray/f310be81be217750fc9d2b233e2ae70c to your computer and use it in GitHub Desktop.
Online / Offline Status Detection w/ Async & Await
/* ********** Online / Offline Detection ********** */
// Request a small image at an interval to determine status
// ** Get a 1x1 pixel image here: http://www.1x1px.me/
// ** Use this code with an HTML element with id="status"
const checkOnlineStatus = async () => {
try {
const online = await fetch("/1pixel.png");
return online.status >= 200 && online.status < 300; // either true or false
} catch (err) {
return false; // definitely offline
}
};
setInterval(async () => {
const result = await checkOnlineStatus();
const statusDisplay = document.getElementById("status");
statusDisplay.textContent = result ? "Online" : "OFFline";
}, 3000); // probably too often, try 30000 for every 30 seconds
// forgot to include async load event listener in the video!
window.addEventListener("load", async (event) => {
const statusDisplay = document.getElementById("status");
statusDisplay.textContent = (await checkOnlineStatus())
? "Online"
: "OFFline";
});
@aishtiaq7
Copy link

when fetching using :
await fetch("/1pixel.png");

it returns this error:
GET http://127.0.0.1:5500/1pixel.png 404 (Not Found)

@dtknepper
Copy link

when fetching using :
await fetch("/1pixel.png");

it returns this error:
GET http://127.0.0.1:5500/1pixel.png 404 (Not Found)

I believe that is because you do not have a file with that name in your directory. If you create a file of 1 pixel in height and width name it pixel1.png and place it in the same folder as this JS file the problem should be solved.

@brnhache
Copy link

when fetching using :
await fetch("/1pixel.png");
it returns this error:
GET http://127.0.0.1:5500/1pixel.png 404 (Not Found)

I believe that is because you do not have a file with that name in your directory. If you create a file of 1 pixel in height and width name it pixel1.png and place it in the same folder as this JS file the problem should be solved.

If it was referencing a local file, how would that indicate an internet connection?

@dtknepper
Copy link

when fetching using :
await fetch("/1pixel.png");
it returns this error:
GET http://127.0.0.1:5500/1pixel.png 404 (Not Found)

I believe that is because you do not have a file with that name in your directory. If you create a file of 1 pixel in height and width name it pixel1.png and place it in the same folder as this JS file the problem should be solved.

If it was referencing a local file, how would that indicate an internet connection?

It wouldn't. But thats for local developement only. Just make sure you put the same files online once you upload it to a server.

@DArtagnan021
Copy link

DArtagnan021 commented Jul 9, 2021

what can i use instead of await fetch("/1pixel.png") in the following code of yours.Its gvien me error while for initialization.
Below down its my..

<script> const checkOnlineStatus = async () => { try { const online = ""; return online.status >= 200 && online.status < 300; // either true or false } catch (err) { return false; // definitely offline } }; setInterval(async () => { const result = await checkOnlineStatus(); const statusDisplay = document.getElementById("<%=lbl_company.ClientID%>"); statusDisplay.textContent = result; if (result == true) { document.getElementById("<%=btnpdf.ClientID%>").style.display = "none"; } else { document.getElementById("<%=btnpdf.ClientID%>").style.display = "block"; } }, 5000); // probably too often, try 30000 for every 30 seconds // forgot to include async load event listener in the video! window.addEventListener("load", async (event) => { const statusDisplay = document.getElementById("<%=lbl_company.ClientID%>"); statusDisplay.textContent = (await checkOnlineStatus()) ? alert("Online") : alert("OFFline"); }); </script>

@DesignByOnyx
Copy link

I recommend using a self-calling timeout rather than setInterval because the request might take a long time on a very slow connection, and you could potentially stack up requests in a way you don't want:

(function pollOnlineStatus() {
  setTimeout(async () => {
    const result = await checkOnlineStatus();
    const statusDisplay = document.getElementById("status");
    statusDisplay.textContent = result ? "Online" : "OFFline";
    pollOnlineStatus(); // self-calling timeout is better than setInterval for this
  }, 3000);
})()

Furthermore, you can consider a really slow internet to be "offline" with the following:

const checkOnlineStatus = () => {
  return new Promise(async (resolve) => {
    let resolved = false;
    // requests longer than 5s are considered "offline"
    const timer = setTimeout(() => {
      resolved = true;
      resolve(false);
    }, 5000);

    try {
      const online = await fetch("/1pixel.png");
      clearTimeout(timer);
      if (!resolved) {
        resolve(online.status >= 200 && online.status < 300); // either true or false
      }
    } catch (err) {
      if (!resolved) {
        resolve(false); // definitely offline
      }
    }
  });
};

@jacobcollinsdev
Copy link

I've found that even when I tick "Offline" in Chrome service workers, the ajax response is true... anyone else had this?

const checkOnlineStatus = async () => {
    try {
      const online = await fetch("/img/1pixel.png",{
          mode: 'no-cors'
      });
      return online.status >= 200 && online.status < 300; // either true or false
    } catch (err) {
      return false; // definitely offline
    }
};

setInterval(async () => {
    const result = await checkOnlineStatus();
    console.log(result)
    const statusDisplay = document.querySelector('.internet-connection');
    statusDisplay.textContent = result ? "Online" : "OFFline";
}, 2000);

@jacobcollinsdev
Copy link

I've found that even when I tick "Offline" in Chrome service workers, the ajax response is true... anyone else had this?

const checkOnlineStatus = async () => {
    try {
      const online = await fetch("/img/1pixel.png",{
          mode: 'no-cors'
      });
      return online.status >= 200 && online.status < 300; // either true or false
    } catch (err) {
      return false; // definitely offline
    }
};

setInterval(async () => {
    const result = await checkOnlineStatus();
    console.log(result)
    const statusDisplay = document.querySelector('.internet-connection');
    statusDisplay.textContent = result ? "Online" : "OFFline";
}, 2000);

Solved this by adding cache: 'no-cache' beneath mode:'no-cors'

@gideongandrapu
Copy link

gideongandrapu commented Jul 22, 2022

Lot of bloatware waiting for you on that website, please don't visit or download any image from 1x1px.me website.
It is just another scam he smoothly pulled out on everyone.

He is just trying to call the local file and that does not indicate any connection to the internet and thats not the correct way to do it.
You are just fetching a local file and it gives success even if don't have active internet connection, cause your browser already must have downloaded it.

@shirooo39
Copy link

isn't it better to just get a response from a server (say, Google) instead of trying to fetch an image?

@DesignByOnyx
Copy link

DesignByOnyx commented Sep 15, 2022

@shirooo39 - companies and services usually prohibit this type of unauthorized requests to their servers, especially for production applications which you are likely using to make money (you don't want someone making unauthorized requests to your servers do you?) One day, Google might even block requests from your domain, or worse, sue you for adding unnecessary load to their servers. You're free to set up a developer account with google, register your app, generate an API key, and ping their APIs in accordance with their EULA - but that seems like a lot of work.

Furthermore, using a self-hosted image provides two metrics: 1) internet connectivity, and 2) a simple "health-check" mechanism to indicate that your server is up and running.

@sofyansitorus
Copy link

I implemented this React, with a bit of modification with the request to the server to fetch HEAD only to the root URL.

Please check the following link:

https://codesandbox.io/s/check-online-offline-status-44ju8p?file=/src/App.tsx

@gitdagray
Copy link
Author

Lot of bloatware waiting for you on that website, please don't visit or download any image from 1x1px.me website. It is just another scam he smoothly pulled out on everyone.

He is just trying to call the local file and that does not indicate any connection to the internet and thats not the correct way to do it. You are just fetching a local file and it gives success even if don't have active internet connection, cause your browser already must have downloaded it.

You can get a 1x1 pixel image from other sites or make your own. I simply shared where I got mine. It is not a "scam". I was trying to be helpful.

Your 2nd paragraph is incorrect. In a dev environment, yes, that would be a local file - HOWEVER, if you host your website on a server and then request that image from the server - it is ALL online. 🤦‍♂️

The points made above about using a self-hosted image by DesignByOnyx are correct. Nailed it! 🚀

I always welcome improvements and I think the suggested "cache: no-cache" setting above by jacobcollinsdev is a good idea. 💯

@MikeGads
Copy link

MikeGads commented Dec 3, 2022

Lot of bloatware waiting for you on that website, please don't visit or download any image from 1x1px.me website. It is just another scam he smoothly pulled out on everyone.
He is just trying to call the local file and that does not indicate any connection to the internet and thats not the correct way to do it. You are just fetching a local file and it gives success even if don't have active internet connection, cause your browser already must have downloaded it.

You can get a 1x1 pixel image from other sites or make your own. I simply shared where I got mine. It is not a "scam". I was trying to be helpful.

Your 2nd paragraph is incorrect. In a dev environment, yes, that would be a local file - HOWEVER, if you host your website on a server and then request that image from the server - it is ALL online. 🤦‍♂️

The points made above about using a self-hosted image by DesignByOnyx are correct. Nailed it! 🚀

I always welcome improvements and I think the suggested "cache: no-cache" setting above by jacobcollinsdev is a good idea. 💯

Tell them to go to https://commons.wikimedia.org/wiki/File:1x1.png

@MikeGads
Copy link

MikeGads commented Dec 3, 2022

I implemented this React, with a bit of modification with the request to the server to fetch HEAD only to the root URL.

Please check the following link:

https://codesandbox.io/s/check-online-offline-status-44ju8p?file=/src/App.tsx

You link is dead, please update

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment