Detect the Internet connection is offline?

后端 未结 19 1402
甜味超标
甜味超标 2020-11-22 00:53

How to detect the Internet connection is offline in JavaScript?

19条回答
  •  情话喂你
    2020-11-22 01:28

    I know this question has already been answered but i will like to add my 10 cents explaining what's better and what's not.

    Window.navigator.onLine

    I noticed some answers spoke about this option but they never mentioned anything concerning the caveat.

    This option involves the use of "window.navigator.onLine" which is a property under Browser Navigator Interface available on most modern browsers. It is really not a viable option for checking internet availability because firstly it is browser centric and secondly most browsers implement this property differently.

    In Firefox: The property returns a boolean value, with true meaning online and false meaning offline but the caveat here is that "the value is only updated when the user follows links or when a script requests a remote page." Hence if the user goes offline and you query the property from a js function or script, the property will always return true until the user follows a link.

    In Chrome and Safari: If the browser is not able to connect to a local area network (LAN) or a router, it is offline; all other conditions return true. So while you can assume that the browser is offline when it returns a false value, you cannot assume that a true value necessarily means that the browser can access the internet. You could be getting false positives, such as in cases where the computer is running a virtualization software that has virtual ethernet adapters that are always "connected".

    The statements above is simply trying to let you know that browsers alone cannot tell. So basically this option is unreliable.

    Sending Request to Own Server Resource

    This involves making HTTP request to your own server resource and if reachable assume internet availability else the user is offline. There are some few caveats to this option.
    1. No server availability is 100% reliant, hence if for some reason your server is not reachable it would be falsely assumed that the user is offline whereas they're connected to the internet.
    2. Multiple request to same resource can return cached response making the http response result unreliable.

    If you agree your server is always online then you can go with this option.

    Here is a simple snippet to fetch own resource:

    // This fetches your website's favicon, so replace path with favicon url
    // Notice the appended date param which helps prevent browser caching.
    fetch('/favicon.ico?d='+Date.now())
      .then(response => {
        if (!response.ok)
          throw new Error('Network response was not ok');
    
       // At this point we can safely assume the user has connection to the internet
            console.log("Internet connection available"); 
      })
      .catch(error => {
      // The resource could not be reached
            console.log("No Internet connection", error);
      });
    

    Sending Request to Third-Party Server Resource

    We all know CORS is a thing.

    This option involves making HTTP request to an external server resource and if reachable assume internet availability else the user is offline. The major caveat to this is the Cross-origin resource sharing which act as a limitation. Most reputable websites blocks CORS requests but for some you can have your way.

    Below a simple snippet to fetch external resource, same as above but with external resource url:

    // Firstly you trigger a resource available from a reputable site
    // For demo purpose you can use the favicon from MSN website
    // Also notice the appended date param which helps skip browser caching.
    fetch('https://static-global-s-msn-com.akamaized.net/hp-neu/sc/2b/a5ea21.ico?d='+Date.now())
      .then(response => {
      // Check if the response is successful
        if (!response.ok)
          throw new Error('Network response was not ok');
    
    // At this point we can safely say the user has connection to the internet
            console.log("Internet available"); 
      })
      .catch(error => {
      // The resource could not be reached
            console.log("No Internet connection", error);
      });
    

    So, Finally for my personal project i went with the 2nd option which involves requesting own server resource because basically there are many factors to tell if there is "Internet Connection" on a user's device, not just from your website container alone nor from a limited browser api.

    Remember your users can also be in an environment where some websites or resources are blocked, prohibited and not accessible which in turn affects the logic of connectivity check. The best bet will be:

    • Try to access a resource on your own server because this is your users environment (Typically i use website's favicon because the response is very light and it is not frequently updated).
    • If there is no connection to the resource, simply say "Error in connection" or "Connection lost" when you need to notify the user rather than assume a broad "No internet connection" which depends on many factors.

提交回复
热议问题