Как обнаружить кросс-браузер онлайн / оффлайн событий?


Я пытаюсь точно определить, когда браузер переходит в автономный режим, используя события HTML5 online и offline.

вот мой код:

<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 с тайм-аутами.

15 92

15 ответов:

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

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

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

события онлайн и оффлайн срабатывает, когда значение этого атрибута изменения.

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

наконец, спецификаций Примечания:

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

основные поставщики браузеров отличаются тем, что означает" офлайн".

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

HTH, -- Чад

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

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

https://github.com/HubSpot/offline

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

здесь тестовая страница. Это красиво/имеет хороший интерфейс обратной связи, кстати! :)

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

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

(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

The window.navigator.onLine атрибут и связанные с ним события в настоящее время ненадежны в некоторых веб-браузерах ( особенно Firefox desktop) как сказал @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');
  }
});

в последнее время 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.

источник: caniuse

навигатор.онлайн-это беспорядок

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

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

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

решение, которое я использую, заключается в том, чтобы самостоятельно контролировать статус с помощью 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);
          }
        });
      }

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

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

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

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

С Уважением,

пожалуйста, найдите требуют.JS модуль, который я написал для форума.

define(['offline'], function (Offline) {
    //Tested with Chrome and IE11 Latest Versions as of 20140412
    //Offline.js - http://github.hubspot.com/offline/ 
    //Offline.js is a library to automatically alert your users 
    //when they've lost internet connectivity, like Gmail.
    //It captures AJAX requests which were made while the connection 
    //was down, and remakes them when it's back up, so your app 
    //reacts perfectly.

    //It has a number of beautiful themes and requires no configuration.
    //Object that will be exposed to the outside world. (Revealing Module Pattern)

    var OfflineDetector = {};

    //Flag indicating current network status.
    var isOffline = false;

    //Configuration Options for Offline.js
    Offline.options = {
        checks: {
            xhr: {
                //By default Offline.js queries favicon.ico.
                //Change this to hit a service that simply returns a 204.
                url: 'favicon.ico'
            }
        },

        checkOnLoad: true,
        interceptRequests: true,
        reconnect: true,
        requests: true,
        game: false
    };

    //Offline.js raises the 'up' event when it is able to reach
    //the server indicating that connection is up.
    Offline.on('up', function () {
        isOffline = false;
    });

    //Offline.js raises the 'down' event when it is unable to reach
    //the server indicating that connection is down.
    Offline.on('down', function () {
        isOffline = true;
    });

    //Expose Offline.js instance for outside world!
    OfflineDetector.Offline = Offline;

    //OfflineDetector.isOffline() method returns the current status.
    OfflineDetector.isOffline = function () {
        return isOffline;
    };

    //start() method contains functionality to repeatedly
    //invoke check() method of Offline.js.
    //This repeated call helps in detecting the status.
    OfflineDetector.start = function () {
        var checkOfflineStatus = function () {
            Offline.check();
        };
        setInterval(checkOfflineStatus, 3000);
    };

    //Start OfflineDetector
    OfflineDetector.start();
    return OfflineDetector;
});

читайте в нашем блоге и дайте мне знать ваши мысли. http://zen-and-art-of-programming.blogspot.com/2014/04/html-5-offline-application-development.html он содержит пример кода с использованием offline.js для определения, когда клиент находится в автономном режиме.

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

FALLBACK:
/online.txt /offline.txt

в html-странице Я использую javascript tot читать содержимое онлайн / оффлайн txt-файла:

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

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

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

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 by document.location.pathname.

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

вот мое решение.

протестировано с IE, Opera, Chrome, FireFox, Safari, как Phonegap WebApp на IOS 8 и как Phonegap WebApp на Android 4.4.2

Это решение не работает с FireFox на localhost.

=================================================================================

onlineCheck.js (путь к файлу: "root/js/onlineCheck.js ):

var isApp = false;

function onLoad() {
        document.addEventListener("deviceready", onDeviceReady, false);
}

function onDeviceReady() {
    isApp = true;
    }


function isOnlineTest() {
    alert(checkOnline());
}

function isBrowserOnline(no,yes){
    //Didnt work local
    //Need "firefox.php" in root dictionary
    var xhr = XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObject('Microsoft.XMLHttp');
    xhr.onload = function(){
        if(yes instanceof Function){
            yes();
        }
    }
    xhr.onerror = function(){
        if(no instanceof Function){
            no();
        }
    }
    xhr.open("GET","checkOnline.php",true);
    xhr.send();
}

function checkOnline(){

    if(isApp)
    {
        var xhr = new XMLHttpRequest();
        var file = "http://dexheimer.cc/apps/kartei/neu/dot.png";

        try {
            xhr.open('HEAD', file , false); 
            xhr.send(null);

            if (xhr.status >= 200 && xhr.status < 304) {
                return true;
            } else {
                return false;
            }
        } catch (e) 
        {
            return false;
        }
    }else
    {
        var tmpIsOnline = false;

        tmpIsOnline = navigator.onLine;

        if(tmpIsOnline || tmpIsOnline == "undefined")
        {
            try{
                //Didnt work local
                //Need "firefox.php" in root dictionary
                var xhr = XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObject('Microsoft.XMLHttp');
                xhr.onload = function(){
                    tmpIsOnline = true;
                }
                xhr.onerror = function(){
                    tmpIsOnline = false;
                }
                xhr.open("GET","checkOnline.php",false);
                xhr.send();
            }catch (e){
                tmpIsOnline = false;
            }
        }
        return tmpIsOnline;

    }
}

=================================================================================

.html (путь к файлу: "root / index.html"):
<!DOCTYPE html>
<html>


<head>
    ...

    <script type="text/javascript" src="js/onlineCheck.js" ></script>

    ...

</head>

...

<body onload="onLoad()">

...

    <div onclick="isOnlineTest()">  
        Online?
    </div>
...
</body>

</html>

=================================================================================

checkOnline.php (путь к файлу: "root"):

<?php echo 'true'; ?> 

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

Wiremonkey плагин на JavaScript а демо вы можете найти здесь

http://ryvan-js.github.io/

Использование Тела Документа:

<body ononline="onlineConditions()" onoffline="offlineConditions()">(...)</body>

Используя Событие Javascript:

window.addEventListener('load', function() {

  function updateOnlineStatus(event) {

    var condition = navigator.onLine ? "online" : "offline";
    if( condition == 'online' ){
        console.log( 'condition: online')
    }else{
        console.log( 'condition: offline')
    }

  }

  window.addEventListener('online',  updateOnlineStatus(event) );
  window.addEventListener('offline', updateOnlineStatus(event) );

});

ссылка:
Документ-Тело:событие ononline
Javascript-Событие:онлайн и оффлайн события

Дополнительные Мысли:
Чтобы отправить вокруг" подключение к сети не то же самое, что подключение к интернету " проблема из приведенных выше методов: вы можете проверить подключение к интернету один раз с ajax при запуске приложения и настройке онлайн/оффлайн-режима. Создайте кнопку повторного подключения для перехода пользователя в интернет. И добавьте на каждый неудачный запрос ajax функцию, которая возвращает пользователя в автономный режим.

вы пробовали использовать сервисных работников? http://www.html5rocks.com/en/tutorials/service-worker/introduction/