Обнаружить интернет-соединение в автономном режиме?

184

Как определить, что подключение к Интернету отключено в JavaScript?

  • 0
    Если вы можете или уже используете веб-сокеты - у веб-сокетов есть событие закрытия, которое необходимо вызвать, если пользователь потерял соединение с сервером.
Теги:
internet-connection
offline
connectivity

17 ответов

123
Лучший ответ

Вы можете определить, что соединение потеряно, выполнив неудачные запросы XHR.

Стандартный подход - повторить запрос несколько раз. Если этого не произойдет, предупредите пользователя, чтобы он проверил соединение, и завершите неудачу.

Примечание: перевод всего приложения в автономное состояние может привести к большой подверженности ошибкам работе с состоянием обработки. Беспроводные соединения могут приходить и уходить и т.д. Поэтому лучше всего просто изящно завершить работу, сохранить данные, и предупредить пользователя.. позволяя им в конечном итоге решить проблему с подключением, если таковая имеется, и продолжать использовать ваше приложение с достаточным количеством прощения.

Примечание. Вы можете проверить наличие надежного сайта, такого как Google, на предмет подключения, но это может быть не совсем полезным, поскольку вы просто пытаетесь сделать свой собственный запрос, потому что, хотя Google может быть доступен, ваше собственное приложение может быть недоступно, и вы все равно будете приходится решать ваши собственные проблемы с подключением. Попытка отправить пинг в Google будет хорошим способом подтвердить, что интернет-соединение само не работает, поэтому, если эта информация вам полезна, то это может стоить хлопот.

Примечание. Отправка Ping может быть осуществлена таким же образом, как если бы вы делали любой двусторонний AJAX-запрос, но отправка Ping в Google в этом случае создаст некоторые проблемы. Во-первых, у нас будут те же междоменные проблемы, которые обычно возникают при создании Ajax-коммуникаций. Один из вариантов - настроить прокси на стороне сервера, при котором мы фактически ping Google (или любой другой сайт) и возвращаем результаты пинга в приложение. Это ловушка 22, потому что если проблема с подключением к Интернету, то мы не сможем добраться до сервера, и если проблема с подключением будет только в нашем собственном домене, мы не сможем заметить разницу, Можно попробовать другие междоменные методы, например, встроить на свою страницу iframe, который указывает на google.com, а затем опросить iframe на предмет успеха/неудачи (проверить содержимое и т.д.). Встраивание изображения может ничего не сказать нам, потому что нам нужен полезный ответ от коммуникационного механизма, чтобы сделать хороший вывод о том, что происходит. Итак, еще раз, определение состояния интернет-соединения в целом может быть больше проблем, чем оно того стоит. Вам придется взвесить эти опции для вашего конкретного приложения.

  • 70
    Повторное «Sidenote» звучит как Дуайт Шруте, говорящий «Вопрос ...» :-)
  • 17
    Почему «catch-22» выделено жирным шрифтом?
Показать ещё 5 комментариев
42

IE 8 будет поддерживать свойство window.navigator.onLine.

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

До тех пор, пока это не произойдет, запрос XHR или Image() или <img> может обеспечить что-то близкое к функциональности, которую вы хотите.

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

Основные браузеры теперь поддерживают это свойство, но ваши результаты будут отличаться.

Цитата из Документация Mozilla:

В Chrome и Safari, если браузер не может подключиться к локальной сети (LAN) или маршрутизатору, он отключен; все остальные условия возвращаются true. Поэтому, когда вы можете предположить, что браузер отключен, когда он возвращает значение false, вы не можете предположить, что истинное значение обязательно означает, что браузер может получить доступ к Интернету. Вы можете получать ложные срабатывания, например, в тех случаях, когда на компьютере работает программное обеспечение для виртуализации с виртуальными адаптерами Ethernet, которые всегда "подключены". Поэтому, если вы действительно хотите определить онлайн-статус браузера, вы должны разработать дополнительные средства для проверки.

В Firefox и Internet Explorer переключение браузера в автономный режим отправляет значение false. Все остальные условия возвращают значение true.

  • 4
    navigator.onLine является частью HTML5 - другие браузеры уже имеют версии для разработки, которые предоставляют его - он уже доступен в Firefox 3 сегодня.
  • 0
    но, к сожалению, недоступен в более ранних версиях IE, которые мы часто должны поддерживать.
Показать ещё 2 комментария
33

Существует несколько способов сделать это:

  • Запрос AJAX на ваш собственный сайт. Если этот запрос терпит неудачу, есть хорошая вероятность, что соединение будет виновато. В документации JQuery содержится раздел обработка неудачных запросов AJAX. Остерегайтесь Same Origin Policy при этом, что может помешать вам получить доступ к сайтам за пределами вашего домена.
  • Вы можете поместить onerror в img, например

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

    Этот метод может также потерпеть неудачу, если исходное изображение будет перемещено/переименовано и, как правило, будет более низким выбором для параметра ajax.

Таким образом, существует несколько различных способов попытаться обнаружить это, но это не идеальный вариант, но при отсутствии возможности выпрыгнуть из изолированной панели браузера и напрямую получить доступ к статусу сетевого подключения пользователя, они, по-видимому, являются лучшими вариантами.

  • 5
    onerror не всегда поддерживается в основных браузерах.
24
 if(navigator.onLine){
  alert('online');
 } else {
  alert('offline');
 }
  • 7
    Всегда возвращает TRUE, если в браузере.
  • 2
    Ну, во-первых, я пытался отключить ТОЛЬКО ЛВС, но он всегда возвращал ИСТИНА. Поэтому, когда я отключил все сети (LAN2, Virtual Box и т. Д.), Он вернул FALSE.
Показать ещё 4 комментария
11

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

9

Как сказал olliej, использование свойства браузера navigator.onLine предпочтительнее, чем отправка сетевых запросов, и, соответственно, developer.mozilla.org/En/Online_and_offline_events, это даже поддерживаемых старыми версиями Firefox и IE.

В последнее время WHATWG указала добавление событий online и offline, если вам нужно отреагировать на изменения navigator.onLine.

Также обратите внимание на ссылку, опубликованную Даниэлем Силвейрой, которая указывает, что использование этих сигналов/свойств для синхронизации с сервером не всегда является хорошей идеей.

  • 0
    ОБНОВЛЕНИЕ: По состоянию на 2015 год, похоже, работает в большинстве браузеров, см. Диаграмму caniuse и статью
8

Вы можете использовать $. ajax() error обратный вызов, который срабатывает, если запрос завершается с ошибкой. Если textStatus равно строке "тайм-аут", это означает, что соединение нарушено:

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

Из doc:

Ошибка: функция, вызываемая, если запрос выходит из строя. Функция передается три arguments: объект XMLHttpRequest, строка, описывающая тип ошибки это произошло и объект исключения, если он произошел. Возможные значения для второго аргумент (кроме нуля) - это "тайм-аут", "ошибка", "немодифицировано" и "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!');
       }
   }
 });
4

ajax-вызов вашего домена - это самый простой способ определить, находитесь ли вы в автономном режиме

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

это просто дать вам концепцию, ее нужно улучшить, проверить коды возврата http и т.д.

4

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

Я использую CodeIgniter и JQuery:

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

function doOnlineCheck(){
    var submitURL = $("#base_path").val() + "index.php/menu/online";//if the server can be reached it returns 1, other wise it times out
    $.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();
        }
    });
}
3

Я думаю, что это очень простой способ.

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

Я искал решение на стороне клиента, чтобы определить, был ли интернет недоступен или мой сервер был отключен. Остальные решения, которые я нашел, всегда, казалось, зависели от стороннего файла script или изображения, что для меня не показалось, что он выдерживает испытание временем. Внешний хостинг script или изображение могут измениться в будущем и привести к сбою кода обнаружения.

Я нашел способ обнаружить его, ища 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 не уверен, почему просто не хотят, чтобы время других людей было потрачено впустую.
  • 0
    Я не думаю, что это будет работать для запрещенных и плохих ошибок запроса :)
0

Почти все основные браузеры теперь поддерживают 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 в OS X и Windows, значение будет соответствовать фактическому сетевому подключению.

(акцент мой)

Это означает, что если window.navigator.onLine имеет значение false (или вы получаете событие в offline), у вас гарантированно не будет подключения к Интернету.

Однако, если это true (или вы получаете online событие), это означает, что система в лучшем случае подключена только к какой-то сети. Это не значит, что у вас есть доступ к интернету например. Чтобы проверить это, вам все равно нужно будет использовать одно из решений, описанных в других ответах.

Первоначально я намеревался опубликовать это как обновление к ответу Гранта Вагнера, но это казалось слишком большой правкой, особенно учитывая, что обновление 2014 года уже не от него.

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

Мой путь.

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

Очень интересный script, который много повторяет:

http://www.codeproject.com/KB/scripting/InternetConnectionTest.aspx

Это очень полезно, потому что он основан на Ajax, является асинхронным, поэтому вы можете проверить, подключен ли Интернет, не выходя из исходной страницы. Используя это с таймером, вы также можете иметь компонент на странице, проверяющий каждые n минут.

-2

Вот фрагмент вспомогательной утилиты, которую у меня есть. Это javascript с именами:

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

Вы должны использовать это с обнаружением метода, иначе сработайте "альтернативный" способ сделать это. Время быстро приближается, когда это будет все, что необходимо. Другие методы - хаки.

  • 11
    Какой в этом смысл?

Ещё вопросы

Сообщество Overcoder
Наверх
Меню