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

Я пытаюсь точно определить, когда браузер отключен, используя онлайн-и HTML-события 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 с тайм-аутами.

Ответ 1

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

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

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

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

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

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

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

Ответ 2

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

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

НТН, - Чад

Ответ 3

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

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

https://github.com/HubSpot/offline

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

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

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

Ответ 4

Лучший способ, который теперь работает во всех основных браузерах, - это Script:

(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

Ответ 5

Атрибут 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 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

С недавнего времени 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

Ответ 7

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

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

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

  • тайм-ауты ajax и вы получите сообщение об ошибке
  • вызов ajax возвращает успех, но msg имеет значение null
  • вызов 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);
          }
        });
      }

Ответ 8

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

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

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

Сообщите нам, если это то, что вы ищете.

С уважением,

Ответ 9

Пожалуйста, найдите модуль require.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 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 для обнаружения, когда клиент находится в автономном режиме.

Ответ 10

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

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.

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

Ответ 11

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

FALLBACK:
/online.txt /offline.txt

В html-странице я использую javascript tot, чтобы прочитать содержимое онлайн файла txt:

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

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

Ответ 12

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

Протестировано с помощью 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;

    }
}

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

index.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'; ?> 

Ответ 13

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

Плагин Javascript для Wiremonkey и демо вы можете найти здесь

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

Ответ 14

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

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

Использование события Javascript:

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

  function updateOnlineStatus() {

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

  }

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

});

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

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