Виявити підключення до Інтернету офлайн?


246

Як виявити підключення до Інтернету офлайн у JavaScript?


Якщо ви можете або вже користуєтеся веб-розетками - у веб-розетках є подія закриття, яку потрібно викликати, якщо користувач втратив зв’язок із сервером.
Саймон

Відповіді:


135

Ви можете визначити, що з'єднання втрачається, роблячи невдалі запити XHR .

Стандартний підхід полягає в повторному повторному запиті . Якщо він не проходить, попередити користувача про те, щоб перевірити з'єднання, і вийти з ладу .

Sidenote: Переведення всієї програми в режим "офлайн" може призвести до безлічі схильних до помилок роботи з обробкою стану .. бездротові з’єднання можуть прийти та йти і т. Д. Тож найкращим варіантом може бути просто витончено вийти з ладу, зберегти Дані та попередити користувача .. дозволяючи їм врешті вирішити проблему з підключенням, якщо така є, та продовжувати використовувати ваш додаток із неабиякою пробачкою.

Sidenote: Ви можете перевірити надійність веб-сайту, наприклад google, на зв’язок, але це може бути не зовсім корисно, як просто спроба зробити власний запит, оскільки, хоча Google може бути доступний, вашої власної програми може не бути, і ви все ще збираєтесь доведеться вирішувати власну проблему з підключенням. Спроба надіслати ping в google - це хороший спосіб підтвердити, що інтернет-з'єднання відсутнє, тож якщо ця інформація буде корисною для вас, то це може бути варте клопоту.

Sidenote : Надсилання Ping може бути досягнуто так само, як і ви будете робити будь-який двосторонній запит на ajax, але надсилання ping в Google, в цьому випадку, представлятиме певні труднощі. По-перше, у нас виникнуть ті самі проблеми, пов’язані з доменом, які зазвичай виникають під час спілкування з Ajax. Один із варіантів - налаштувати проксі-сервер, на якому ми фактично знаходимо pinggoogle (або будь-який інший сайт) та повертаємо результати програми в додаток. Це улов-22тому що, якщо насправді проблема з підключенням до Інтернету, ми не зможемо потрапити на сервер, і якщо проблема з підключенням є лише на нашому власному домені, ми не зможемо визначити різницю. Інші міждоменні методи можна спробувати, наприклад, вставити на вашу сторінку iframe, що вказує на google.com, а потім опитувати iframe для успіху / провалу (вивчити вміст тощо). Вставлення зображення може насправді нічого нам не сказати, оскільки нам потрібна корисна відповідь від механізму комунікації, щоб зробити хороший висновок про те, що відбувається. Отже, знову ж таки визначити стан підключення до Інтернету в цілому може бути більше проблем, ніж варто. Вам доведеться зважити ці параметри для конкретного додатка.


84
Неодноразовий "Sidenote" звучить як Дуайт Шруте, що говорить "Запитання ..." :-)
Брайан Келлі

19
Чому "catch-22" жирним шрифтом?
codingbear

33
Тепер у 2012 році ви можете перевірити змінну navigator.onLine;)
Жоао Пінто Єрунімо

13
Навігація navigator.online/offline також ненадійна з тих самих причин. Див stackoverflow.com/questions/3181080 / ...
Efran Cobisi

17
Ви можете перевірити Offline.js , бібліотеку з відкритим кодом, побудовану саме для цієї мети.
Адам

51

IE 8 підтримуватиме властивість window.navigator.onLine .

Але, звичайно, це не допомагає іншим браузерам або операційним системам. Я прогнозую, що інші постачальники браузерів вирішать надати цю власність, враховуючи важливість знання статусу в режимі онлайн / офлайн в додатках Ajax.

Поки цього не станеться, або XHR або Image()або <img>запит може надати що - то близько до функціональності ви хочете.

Оновлення (2014/11/16)

Зараз основні веб-переглядачі підтримують цю властивість, але результати варіюватимуться.

Цитата з документації Mozilla :

У Chrome і Safari, якщо браузер не в змозі підключитися до локальної мережі (LAN) або маршрутизатора, він перебуває в автономному режимі; всі інші умови повертаються true. Отже, хоча ви можете припустити, що браузер перебуває в автономному режимі, коли він повертає falseзначення, ви не можете припустити, що справжнє значення обов'язково означає, що браузер може отримати доступ до Інтернету. Можливо, ви отримаєте помилкові позитиви, як-от у випадках, коли на комп'ютері працює програмне забезпечення для віртуалізації, яке має віртуальні адаптери Ethernet, які завжди "підключені". Тому, якщо ви дійсно хочете визначити статус браузера в Інтернеті, вам слід розробити додаткові засоби для перевірки.

У Firefox та Internet Explorer перехід браузера в офлайн-режим пересилає falseзначення. Усі інші умови повертають trueзначення.


5
navigator.onLine є частиною HTML5 - інші браузери вже мають версії розробки, які її надають - вона вже доступна у Firefox 3 сьогодні.
olliej

-але, на жаль, недоступний у попередніх версіях IE, який нам часто потрібно підтримувати.
кепаро

22
navigator.onLine показує стан браузера, а не власне з'єднання. Таким чином, у вас може бути встановлений браузер ур для onLine, але він насправді не зможе, оскільки з'єднання не працює. Navigator.onLine буде помилковим лише у тому випадку, якщо для веб-переглядача встановлено режим перегляду офлайн.

5
якщо я вимикаю WI-FI на своєму Nexus7, на сторінці все одно йдеться про те, що navigator.onLine - ІСТИНА. Погано ...
walv

42

Зараз майже всі основні браузери підтримують window.navigator.onLineвластивість, а також відповідні події onlineта offlineвікна:

window.addEventListener('online', () => console.log('came online'));
window.addEventListener('offline', () => console.log('came offline'));

Спробуйте встановити систему чи браузер в режимі офлайн / онлайн і перевірте консоль чи window.navigator.onLineвластивість на зміну значення. Ви також можете протестувати на цьому веб-сайті .

Зауважте, однак цю цитату з документації Mozilla :

У Chrome і Safari, якщо браузер не в змозі підключитися до локальної мережі (LAN) або маршрутизатора, він перебуває в автономному режимі; всі інші умови повертаються true. Отже, хоча ви можете припустити, що браузер перебуває в автономному режимі, коли він повертає falseзначення , ви не можете припустити, що trueзначення обов'язково означає, що браузер може отримати доступ до Інтернету . Можливо, ви отримаєте помилкові позитиви, як-от у випадках, коли на комп'ютері працює програмне забезпечення для віртуалізації, яке має віртуальні адаптери Ethernet, які завжди "підключені". Тому, якщо ви дійсно хочете визначити статус браузера в Інтернеті, вам слід розробити додаткові засоби для перевірки.

У Firefox та Internet Explorer перехід браузера в офлайн-режим пересилає falseзначення. Поки Firefox 41, всі інші умови повертають trueзначення; оскільки Firefox 41 для ОС X і Windows значення буде слідувати фактичному підключенню до мережі.

(акцент - мій власний)

Це означає , що якщо window.navigator.onLineє false(або ви отримуєте offlineподія), ви гарантовано не мати підключення до Інтернету.

Якщо це trueвсе-таки (або ви отримуєте onlineподію), це означає лише, що система підключена до якоїсь мережі, в кращому випадку. Це не означає, що у вас, наприклад, доступ до Інтернету. Щоб перевірити це, вам все одно потрібно буде використовувати одне з рішень, описаних в інших відповідях.

Я спочатку мав намір опублікувати це як оновлення відповіді Гранта Вагнера , але це здалося занадто великим редагуванням, особливо враховуючи, що оновлення 2014 року вже не від нього .


Найкраща відповідь. Дякую.
vibs2006

1
Нещодавно у мене була можливість трохи попрацювати над поведінкою в режимі офлайн. Події чудово використовувати, АЛЕ ios safari створить проблеми. Коли ви вмикаєте Інтернет на своєму телефоні, події в режимі офлайн / онлайн затягуватимуться на 2 секунди, і це може бути проблематично з причин візуального відображення, оскільки ви не можете передбачити майбутнє. Це просто щось, що я хотів згадати і могло б комусь допомогти.
TeeJaay

38

Існує кілька способів зробити це:

  • Запит AJAX на власний веб-сайт. Якщо цей запит не вдасться, є велика ймовірність, що це з'єднання винне. Документація JQuery містить розділ щодо обробки невдалих запитів AJAX . Остерігайтеся тієї ж політики щодо оригіналу, якщо це робити, що може заважати вам отримувати доступ до сайтів за межами вашого домену.
  • Ви можете поставити onerrorтакий img, як

    <img src='http://www.example.com/singlepixel.gif' 
          onerror='alert("Connection dead");' />

    Цей метод також може бути невдалим, якщо вихідне зображення буде переміщено / перейменовано, і, як правило, буде неповноцінним вибором для параметра ajax.

Отже, є кілька різних способів спробувати виявити це, жоден ідеальний, але за відсутності можливості вистрибувати з пісочної скриньки браузера та безпосередньо отримувати доступ до статусу чистого з'єднання користувача, вони здаються найкращими варіантами.


36
 if(navigator.onLine){
  alert('online');
 } else {
  alert('offline');
 }

11
Він завжди повертається ІСТИНА, якщо в браузері.
Славчо

2
Ну, спершу я намагався вимкнути ТОЛЬКУ LAN, але це завжди поверталося ПРАВИЛЬНО. Тож коли я відключив усі мережі (LAN2, Virtual Box тощо), він повернувся ЛІЖНО.
Славчо

3
Ця відповідь дублює декілька існуючих відповідей за три роки тому.
JasonMArcher

2
він не перевіряє підключення до Інтернету, він перевіряє лише підключення до локальної мережі
Suganth G

Працював для мене в HTML 5, JavaScript, в mac book (використовуючи wifi), навіть працював у мобільному. але проблема полягає в тому, що коли wifi на ньому повертається ІСТИНА кожен раз, навіть я вимикаю Wi-Fi навпаки.
С.Ядав

11

API кешування додатків HTML5 вказує navigator.onLine, який наразі доступний у бета-версіях IE8, WebKit (наприклад, Safari), і вже підтримується у Firefox 3


11

Ви можете використовувати $ .ajax () «s errorзворотного виклику, який спрацьовує , якщо запит не вдається. Якщо textStatusдорівнює рядок "timeout", це, ймовірно, означає, що з'єднання розірвано:

function (XMLHttpRequest, textStatus, errorThrown) {
  // typically only one of textStatus or errorThrown 
  // will have info
  this; // the options for this ajax request
}

Від док .

Помилка : Функція, яку потрібно викликати, якщо запит не працює. Функції передаються три аргументи: Об'єкт XMLHttpRequest, рядок, що описує тип помилки, що сталася, і необов'язковий об'єкт виключення, якщо такий стався. Можливими значеннями для другого аргументу (крім нульового) є "timeout", "error", "notmodified" та "parsererror". Це подія Ajax

Так, наприклад:

 $.ajax({
   type: "GET",
   url: "keepalive.php",
   success: function(msg){
     alert("Connection active!")
   },
   error: function(XMLHttpRequest, textStatus, errorThrown) {
       if(textStatus == 'timeout') {
           alert('Connection seems dead!');
       }
   }
 });

9

Як сказав olliej, використання navigator.onLineвластивості браузера є кращим, ніж надсилання мережевих запитів, і відповідно з developer.mozilla.org/En/Online_and_offline_events воно навіть підтримується старими версіями Firefox та IE.

Нещодавно WHATWG уточнив доповнення onlineта offlineподії, якщо вам потрібно буде реагувати на navigator.onLineзміни.

Будь ласка, зверніть увагу на посилання, розміщене Даніелем Сільвейрою, яке вказує, що посилатися на цей сигнал / властивість для синхронізації з сервером не завжди є хорошою ідеєю.


ОНОВЛЕННЯ: Станом на 2015 рік, здається, працює в більшості браузерів, дивіться діаграму та статтю
Ольга

8
window.navigator.onLine

це те, що ви шукаєте, але мало чого тут додати, по-перше, якщо це щось у вашій програмі, яке ви хочете перевірити (хотіли б побачити, чи несподівано користувач раптово перейде в офлайн, що виправляє в цьому випадку більшість часу, то ви потрібно також слухати зміни), для цього ви додаєте слухача подій у вікно, щоб виявити будь-які зміни, і для перевірки, чи користувач переходить в офлайн, ви можете зробити:

window.addEventListener("offline", 
  ()=> console.log("No Internet")
);

і для перевірки наявності в Інтернеті:

window.addEventListener("online", 
  ()=> console.log("Connected Internet")
);

2
Ви повинні бути обережними onLine. Веб-переглядачі визначають стан перебування в Інтернеті дуже по-різному. Погляньте на developer.mozilla.org/en-US/docs/Web/API/NavigatorOnLine/onLine .
Андреас Баумгарт

1
Ваша відповідь неправильна. Властивість "onLine" не має нічого спільного з Інтернет-спільністю. Дивіться посилання вище про веб-програми.
Олександр В.

7

Мені довелося зробити веб-додаток (на базі ajax) для замовника, який багато працює з школами, у цих школах часто погане з'єднання з Інтернетом. Я використовую цю просту функцію, щоб виявити, чи є зв’язок, працює дуже добре!

Я використовую CodeIgniter та Jquery:

function checkOnline() {
    setTimeout("doOnlineCheck()", 20000);
}

function doOnlineCheck() {
    //if the server can be reached it returns 1, other wise it times out
    var submitURL = $("#base_path").val() + "index.php/menu/online";

    $.ajax({
        url : submitURL,
        type : "post",
        dataType : "msg",
        timeout : 5000,
        success : function(msg) {
            if(msg==1) {
                $("#online").addClass("online");
                $("#online").removeClass("offline");
            } else {
                $("#online").addClass("offline");
                $("#online").removeClass("online");
            }
            checkOnline();
        },
        error : function() {
            $("#online").addClass("offline");
            $("#online").removeClass("online");
            checkOnline();
        }
    });
}

6

виклик Ajax до вашого домену - це найпростіший спосіб виявити, чи ви перебуваєте в автономному режимі

$.ajax({
      type: "HEAD",
      url: document.location.pathname + "?param=" + new Date(),
      error: function() { return false; },
      success: function() { return true; }
   });

це лише для того, щоб дати вам концепцію, її слід вдосконалити.

Наприклад, помилка = 404 все ще повинна означати, що ви в Інтернеті


4

Я думаю, що це дуже простий спосіб.

var x = confirm("Are you sure you want to submit?");
if (x) {
  if (navigator.onLine == true) {
    return true;
  }
  alert('Internet connection is lost');
  return false;
}
return false;

onLine не означає, що є інтернет. За інформацією developer.mozilla.org/en-US/docs/Web/API/NavigatorOnLine/onLine 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
Шмуель Каменський

2

Я шукав рішення на стороні клієнта, щоб визначити, чи не працював Інтернет чи не працював мій сервер. Інші рішення, які я знайшов, завжди здавалися залежними від сторонніх файлів або зображень скрипту, що мені не здавалося, що це витримає перевірку часом. Зовнішній розміщений сценарій або зображення можуть змінитися в майбутньому і призвести до збою коду виявлення.

Я знайшов спосіб виявити це, шукаючи xhrStatus з кодом 404. Крім того, я використовую JSONP, щоб обійти обмеження CORS. Код статусу, відмінний від 404, показує, що інтернет-з'єднання не працює.

$.ajax({
    url:      'https://www.bing.com/aJyfYidjSlA' + new Date().getTime() + '.html',
    dataType: 'jsonp',
    timeout:  5000,

    error: function(xhr) {
        if (xhr.status == 404) {
            //internet connection working
        }
        else {
            //internet is down (xhr.status == 0)
        }
    }
});

2
Це не працює, як 10-5-2016 не впевнений, чому просто не хочеться витрачати час інших людей.
Брен

Я не думаю, що це буде працювати для заборонених і поганих помилок запиту :)
Faisal Naseer

1

Мій шлях.

<!-- the file named "tt.jpg" should exist in the same directory -->

<script>
function testConnection(callBack)
{
    document.getElementsByTagName('body')[0].innerHTML +=
        '<img id="testImage" style="display: none;" ' +
        'src="tt.jpg?' + Math.random() + '" ' +
        'onerror="testConnectionCallback(false);" ' +
        'onload="testConnectionCallback(true);">';

    testConnectionCallback = function(result){
        callBack(result);

        var element = document.getElementById('testImage');
        element.parentNode.removeChild(element);
    }    
}
</script>

<!-- usage example -->

<script>
function myCallBack(result)
{
    alert(result);
}
</script>

<a href=# onclick=testConnection(myCallBack);>Am I online?</a>

1

Проблема деяких методів, таких navigator.onLineяк те, що вони не сумісні з деякими браузерами та мобільними версіями. Опція, яка мені дуже допомогла, полягала в тому, щоб використовувати класичний XMLHttpRequestметод, а також передбачити можливий випадок, коли файл зберігається в кеші з відповіддю XMLHttpRequest.statusбільше, ніж 200 і менше 304.

Ось мій код:

 var xhr = new XMLHttpRequest();
 //index.php is in my web
 xhr.open('HEAD', 'index.php', true);
 xhr.send();

 xhr.addEventListener("readystatechange", processRequest, false);

 function processRequest(e) {
     if (xhr.readyState == 4) {
         //If you use a cache storage manager (service worker), it is likely that the
         //index.php file will be available even without internet, so do the following validation
         if (xhr.status >= 200 && xhr.status < 304) {
             console.log('On line!');
         } else {
             console.log('Offline :(');
         }
     }
}

0

Є два варіанти відповіді на два різних сенарі:

  1. Якщо ви використовуєте JavaScript на веб-сайті (тобто; або будь-якій передній частині) Найпростіший спосіб зробити це:

    <h2>The Navigator Object</h2>
    
    <p>The onLine property returns true if the browser is online:</p>
    
    <p id="demo"></p>
    
    <script>
      document.getElementById("demo").innerHTML = "navigator.onLine is " + navigator.onLine;
    </script>

  2. Але якщо ви використовуєте js на стороні сервера (тобто; вузол тощо), ви можете визначити, що з'єднання втрачається, роблячи невдалі запити XHR.

    Стандартний підхід полягає в повторному повторному запиті. Якщо він не проходить, попередити користувача про те, щоб перевірити з'єднання, і вийти з ладу.


0

помилка в запиті

$.ajax({
    url: /your_url,
    type: "POST or GET",
    data: your_data,
    success: function(result){
      //do stuff
    },
    error: function(xhr, status, error) {

      //detect if user is online and avoid the use of async
        $.ajax({
            type: "HEAD",
            url: document.location.pathname,
            error: function() { 
              //user is offline, do stuff
              console.log("you are offline"); 
              }
         });
    }   
});

-1

Ось фрагмент допоміжної утиліти, яку я маю. Це javascript у розмірі з іменами:

network: function() {
    var state = navigator.onLine ? "online" : "offline";
    return state;
}

Вам слід скористатися цим методом виявлення іншого способу виявлення "альтернативного" способу цього. Швидко наближається час, коли це буде все, що потрібно. Інші методи - хаки.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.