web-dev-qa-db-ja.com

オンライン/オフラインイベントのクロスブラウザを検出する方法は?

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呼び出しを繰り返すことは避けたいです。

104
Pierre Duplouy

ブラウザのベンダーは、オフラインを定義する方法に同意できません。一部のブラウザには、オフラインアクセス機能があります。これは、ネットワークアクセスの欠如とは別に考えますが、これもインターネットアクセスとは異なります。全体が混乱です。一部のブラウザベンダーは、実際のネットワークアクセスが失われたときにnavigator.onLineフラグを更新しますが、他のベンダーは更新しません。

仕様から:

ユーザーエージェントが完全にオフライン(ネットワークから切断)の場合はfalseを返します。ユーザーエージェントがオンラインである可能性がある場合、trueを返します。

この属性の値が変更されると、オンラインおよびオフラインのイベントが発生します。

Navigator.onLine属性は、ユーザーがリンクをたどるとき、またはスクリプトがリモートページを要求するとき(またはそのような試みが失敗することを知っているとき)、ユーザーエージェントがネットワークに接続しない場合はfalseを返し、そうでない場合はtrueを返す必要があります。

最後に、仕様では次のことに注意してください。

この属性は本質的に信頼できません。インターネットにアクセスしなくても、コンピューターをネットワークに接続できます。

66
Rebecca

主要なブラウザベンダーは、「オフライン」の意味が異なります。

ChromeとSafariは、「オフライン」になると自動的に検出します。つまり、ネットワークケーブルを抜くと、「オンライン」イベントとプロパティが自動的に起動します。

Firefox(Mozilla)、Opera、およびIEは異なるアプローチを取り、ブラウザで明示的に「オフラインモード」を選択しない限り、「オンライン」であると見なします(ネットワーク接続が機能していない場合でも)。

Firefox/Mozillaの動作には有効な引数があり、このバグレポートのコメントに概要が示されています。

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

しかし、質問に答えるために-あなたは実際にネットワーク接続があるかどうかを検出するためにオンライン/オフラインイベント/プロパティに頼ることはできません。

代わりに、別のアプローチを使用する必要があります。

このMozilla Developer記事の「Notes」セクションには、2つの代替方法へのリンクがあります。

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、チャド

31
thewoolleyman

今日、この仕事をするオープンソースのJavaScriptライブラリがあります。それは Offline.js と呼ばれています。

オンライン/オフライン表示をユーザーに自動的に表示します。

https://github.com/HubSpot/offline

完全に README を確認してください。フックできるイベントが含まれています。

テストページ です。それは美しい/素敵なフィードバックUIがあります! :)

Offline.js Simulate UIは、ブルートフォースメソッドを使用して実際の接続を無効にすることなく、ページがさまざまな接続状態にどのように応答するかをテストできるOffline.jsプラグインです。

18

すべての主要なブラウザで現在動作する最良の方法は、次のスクリプトです。

(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

15
tmaximini

window.navigator.onLine 属性とその関連イベントは、特定のWebブラウザーでは現在信頼できません( 特に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');
  }
});
11
Epoc

最近以来、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

10
Haroen Viaene

navigator.onLineは混乱です

サーバーにajax呼び出しをしようとすると、私はこれに直面します。

クライアントがオフラインの場合、いくつかの状況が考えられます。

  • ajax呼び出しがタイムアウトし、エラーが表示される
  • ajax呼び出しは成功を返しますが、msgはnullです
  • ブラウザがそのように決定するため、ajax呼び出しは実行されません(これは、しばらくしてnavigator.onLineがfalseになる場合です)

私が使用している解決策は、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);
          }
        });
      }
7
Toolkit

HTML5では、navigator.onLineプロパティを使用できます。ここを見て:

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

おそらく、JavaScriptは「ブラウザ」変数を準備し、オフラインかオンラインかを認識しますが、実際にはネットワーク接続をチェックしないため、現在の動作はランダムです。

これがあなたが探しているものかどうかを教えてください。

敬具、

5
Trefex

オフライン用に作成した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'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を使用してクライアントがオフラインになったことを検出します。

2

HTML5キャッシュマニフェストでFALLBACKオプションを使用して、次の方法でhtml5アプリがオンラインかオフラインかを確認します。

FALLBACK:
/online.txt /offline.txt

HTMLページでは、javascript totを使用してオンライン/オフラインのtxtファイルの内容を読み取ります。

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

オフラインの場合、スクリプトはoffline.txtの内容を読み取ります。ファイル内のテキストに基づいて、Webページがオンラインかオフラインかを検出できます。

2
Marcel Scholte

以下のようにオフラインのクロスブラウザ方法を簡単に検出できます

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に置き換えることができます。

ソリューションの要点は、接続できない場合はドメイン名に接続してみることです。オフラインになります。クロスブラウザで動作します。

2
harishr

ドキュメント本文の使用:

<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-Event: オンラインおよびオフラインイベント

追加の考え:
「ネットワーク接続はインターネット接続とは異なります」を回避するために上記の方法の問題:アプリケーションの起動時にajaxでインターネット接続を1回確認し、オンライン/オフラインモードを構成できます。ユーザーがオンラインになるための再接続ボタンを作成します。そして、失敗した各ajaxリクエストに、ユーザーをオフラインモードに戻す機能を追加します。

0
Milingu Kilu

これが私の解決策です。

IE、Opera、Chrome、FireFox、SafariでIOS 8のPhonegap WebAppおよびAndroid 4.4.2のPhonegap WebAppでテスト済み

このソリューションは、localhost上のFireFoxでは機能しません。

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

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(ファイルパス:「ルート」):

<?php echo 'true'; ?> 
0
JoJoWhatsUp

さて、ブラウザ接続をリアルタイムで監視し、インターネットまたはインターネットとのブラウザ接続がダウンした場合にユーザーに通知できるjavascriptプラグインを試すことができます。

Wiremonkey Javascriptプラグイン およびここにあるデモ

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

0
Ry Van