Как обнаружить онлайн / офлайн кроссбраузер событий? - PullRequest
103 голосов
/ 05 июля 2010

Я пытаюсь точно определить, когда браузер отключается, используя HTML5 онлайн и офлайн события.

Вот мой код:

<script>
    // FIREFOX
    $(window).bind("online", applicationBackOnline); 
    $(window).bind("offline", applicationOffline);

    //IE
    window.onload = function() {
        document.body.ononline = IeConnectionEvent;
        document.body.onoffline = IeConnectionEvent;
    } 
</script>

Это прекрасно работает, когда я просто нажимаю «Работать в автономном режиме» на Firefox или IE, но это вроде случайной работы, когда я на самом деле отключаю провод.

Какой лучший способ обнаружить это изменение? Я хотел бы избежать повторения вызовов ajax с таймаутами.

Ответы [ 14 ]

64 голосов
/ 27 января 2011

Поставщики браузеров не могут договориться о том, как определить автономный режим.Некоторые браузеры имеют функцию «Работа в автономном режиме», которую они рассматривают отдельно от отсутствия доступа к сети, что опять-таки отличается от доступа в Интернет.Все это беспорядок.Некоторые поставщики браузеров обновляют флаг navigator.onLine, когда фактический доступ к сети теряется, другие - нет.

Из спецификации:

Возвращает false, если пользовательский агент определенно находится в автономном режиме (отключен от сети).Возвращает значение true, если пользовательский агент может находиться в сети.

События в сети и в автономном режиме генерируются при изменении значения этого атрибута.

Атрибут navigator.onLine должен возвращать значение false, если пользовательский агент будетне связываться с сетью, когда пользователь переходит по ссылкам или когда скрипт запрашивает удаленную страницу (или знает, что такая попытка потерпит неудачу), и должен возвращать true в противном случае.

Наконец, спецификация отмечает:

Этот атрибут по своей природе ненадежен.Компьютер может быть подключен к сети без доступа в Интернет.

31 голосов
/ 13 марта 2012

Основные поставщики браузеров расходятся во мнении о том, что означает «офлайн».

Chrome и Safari обнаружат, когда вы перейдете в автономный режим, что означает, что «онлайн» события и свойства будут срабатывать автоматически при отключении сетевого кабеля.

Firefox (Mozilla), Opera и IE используют другой подход и считают вас «онлайн», если вы явно не выберете «Автономный режим» в браузере - даже если у вас нет рабочего сетевого подключения.

Есть допустимые аргументы для поведения Firefox / Mozilla, которые изложены в комментариях к этому сообщению об ошибке:

https://bugzilla.mozilla.org/show_bug.cgi?id=654579

Но, чтобы ответить на вопрос - вы не можете полагаться на онлайн / офлайн события / свойство, чтобы определить, действительно ли существует сетевое подключение.

Вместо этого вы должны использовать альтернативные подходы.

Раздел «Примечания» этой статьи для разработчиков Mozilla содержит ссылки на два альтернативных метода:

https://developer.mozilla.org/en/Online_and_offline_events

«Если API не реализован в браузере, вы можете использовать другие сигналы, чтобы определить, не в сети ли вы, включая прослушивание событий ошибок AppCache и ответов из XMLHttpRequest»

Это ссылка на пример подхода «прослушивание событий ошибки AppCache»:

http://www.html5rocks.com/en/mobile/workingoffthegrid/#toc-appcache

... и пример подхода «прослушивание сбоев XMLHttpRequest»:

http://www.html5rocks.com/en/mobile/workingoffthegrid/#toc-xml-http-request

НТН, - Чад

18 голосов
/ 28 мая 2014

Сегодня есть библиотека JavaScript с открытым исходным кодом, которая выполняет эту работу: она называется Offline.js.

Автоматически отображать онлайн / автономную индикацию для ваших пользователей.

https://github.com/HubSpot/offline

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

Вот тестовая страница . Это красиво / имеет приятный интерфейс обратной связи, кстати! :)

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

15 голосов
/ 23 августа 2013

Лучший способ, который работает сейчас на всех основных браузерах, это следующий скрипт:

(function () {
    var displayOnlineStatus = document.getElementById("online-status"),
        isOnline = function () {
            displayOnlineStatus.innerHTML = "Online";
            displayOnlineStatus.className = "online";
        },
        isOffline = function () {
            displayOnlineStatus.innerHTML = "Offline";
            displayOnlineStatus.className = "offline";
        };

    if (window.addEventListener) {
        /*
            Works well in Firefox and Opera with the 
            Work Offline option in the File menu.
            Pulling the ethernet cable doesn't seem to trigger it.
            Later Google Chrome and Safari seem to trigger it well
        */
        window.addEventListener("online", isOnline, false);
        window.addEventListener("offline", isOffline, false);
    }
    else {
        /*
            Works in IE with the Work Offline option in the 
            File menu and pulling the ethernet cable
        */
        document.body.ononline = isOnline;
        document.body.onoffline = isOffline;
    }
})();

Источник: http://robertnyman.com/html5/offline/online-offline-events.html

10 голосов
/ 01 апреля 2016

С недавних пор navigator.onLine показывает то же самое во всех основных браузерах и поэтому может использоваться.

if (navigator.onLine) {
  // do things that need connection
} else {
  // do things that don't need connection
}

Самыми старыми версиями, которые поддерживают это правильно, являются: Firefox 41 , IE 9, Chrome 14 и Safari 5.

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

Предыдущаядо FF 41 показывалось бы false, только если пользователь вручную перевел браузер в автономный режим.В IE 8 свойство находилось в body вместо window.

source: caniuse

10 голосов
/ 17 февраля 2015

Атрибут window.navigator.onLine и связанные с ним события в настоящее время ненадежны в некоторых веб-браузерах ( особенно для рабочего стола Firefox ), как сказал @Junto, поэтому я написал небольшую функцию (используя jQuery), которые периодически проверяют состояние сетевого подключения и поднимают соответствующее событие offline и online:

// Global variable somewhere in your app to replicate the 
// window.navigator.onLine variable (it is not modifiable). It prevents
// the offline and online events to be triggered if the network
// connectivity is not changed
var IS_ONLINE = true;

function checkNetwork() {
  $.ajax({
    // Empty file in the root of your public vhost
    url: '/networkcheck.txt',
    // We don't need to fetch the content (I think this can lower
    // the server's resources needed to send the HTTP response a bit)
    type: 'HEAD',
    cache: false, // Needed for HEAD HTTP requests
    timeout: 2000, // 2 seconds
    success: function() {
      if (!IS_ONLINE) { // If we were offline
        IS_ONLINE = true; // We are now online
        $(window).trigger('online'); // Raise the online event
      }
    },
    error: function(jqXHR) {
      if (jqXHR.status == 0 && IS_ONLINE) {
        // We were online and there is no more network connection
        IS_ONLINE = false; // We are now offline
        $(window).trigger('offline'); // Raise the offline event
      } else if (jqXHR.status != 0 && !IS_ONLINE) {
        // All other errors (404, 500, etc) means that the server responded,
        // which means that there are network connectivity
        IS_ONLINE = true; // We are now online
        $(window).trigger('online'); // Raise the online event
      }
    }
  });
}

Вы можете использовать его следующим образом:

// Hack to use the checkNetwork() function only on Firefox 
// (http://stackoverflow.com/questions/5698810/detect-firefox-browser-with-jquery/9238538#9238538)
// (But it may be too restrictive regarding other browser
// who does not properly support online / offline events)
if (!(window.mozInnerScreenX == null)) {
    window.setInterval(checkNetwork, 30000); // Check the network every 30 seconds
}

Для прослушивания оффлайн и онлайн событий (с помощью jQuery):

$(window).bind('online offline', function(e) {
  if (!IS_ONLINE || !window.navigator.onLine) {
    alert('We have a situation here');
  } else {
    alert('Battlestation connected');
  }
});
6 голосов
/ 22 июня 2011

navigator.onLine - беспорядок

Я сталкиваюсь с этим при попытке выполнить ajax-вызов на сервер.

Есть несколько возможных ситуаций, когда клиент находится в автономном режиме:

  • тайм-аут вызова ajax, и вы получаете ошибку
  • вызов ajax возвращает успех, но сообщение имеет нулевое значение
  • вызов ajax не выполняется, потому что браузер решает, так (это когда navigator.onLine через некоторое время становится ложным)

Решение, которое я использую, состоит в том, чтобы самостоятельно контролировать статус с помощью javascript.Я устанавливаю условие успешного вызова, в любом другом случае я предполагаю, что клиент находится в автономном режиме.Как то так:

var offline;
pendingItems.push(item);//add another item for processing
updatePendingInterval = setInterval("tryUpdatePending()",30000);
tryUpdatePending();

    function tryUpdatePending() {

        offline = setTimeout("$('#offline').show()", 10000);
        $.ajax({ data: JSON.stringify({ items: pendingItems }), url: "WebMethods.aspx/UpdatePendingItems", type: "POST", dataType: "json", contentType: "application/json; charset=utf-8",
          success: function (msg) {
            if ((!msg) || msg.d != "ok")
              return;
            pending = new Array(); //empty the pending array
            $('#offline').hide();
            clearTimeout(offline);
            clearInterval(updatePendingInterval);
          }
        });
      }
5 голосов
/ 05 июля 2010

В HTML5 вы можете использовать свойство navigator.onLine. Смотрите здесь:

http://www.w3.org/TR/offline-webapps/#related

Вероятно, ваше текущее поведение является случайным, поскольку javascript только подготавливает переменную "browser", а затем узнает, подключены ли вы в автономном режиме и онлайн, но на самом деле он не проверяет сетевое соединение.

Дайте нам знать, если это то, что вы ищете.

С уважением,

2 голосов
/ 08 марта 2016

Я использую опцию FALLBACK в манифесте кэша HTML5, чтобы проверить, подключено ли мое html5-приложение к сети:

FALLBACK:
/online.txt /offline.txt

На html-странице я использую javascript для чтения содержимого онлайн / оффлайн текстового файла:

<script>$.get( "urlto/online.txt", function( data ) {
$( ".result" ).html( data );
alert( data );
});</script>

В автономном режиме скрипт будет читать содержимое файла offline.txt. На основании текста в файлах вы можете определить, находится ли веб-страница в автономном режиме.

2 голосов
/ 22 апреля 2015

Вы можете легко обнаружить кросс-браузерный способ, как показано ниже

var randomValue = Math.floor((1 + Math.random()) * 0x10000)

$.ajax({
      type: "HEAD",
      url: "http://yoururl.com?rand=" + randomValue,
      contentType: "application/json",
      error: function(response) { return response.status == 0; },
      success: function() { return true; }
   });

Вы можете заменить yoururl.com на document.location.pathname.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...