115

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 呼び出しを繰り返さないようにしたい。

4

14 に答える 14

72

2011 年現在、さまざまなブラウザー ベンダーがオフラインの定義方法について合意できていません。一部のブラウザーにはオフライン作業機能があり、ネットワーク アクセスの欠如とは別のものと見なされますが、これもまたインターネット アクセスとは異なります。全体がめちゃくちゃです。一部のブラウザー ベンダーは、実際のネットワーク アクセスが失われたときに navigator.onLine フラグを更新しますが、更新しないベンダーもあります。

仕様から:

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

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

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

最後に、仕様は次のとおりです。

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

于 2011-01-27T06:30:22.317 に答える
34

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

Chrome、Safari、および Firefox (バージョン 41 以降) は、「オフライン」になると自動的に検出します。つまり、ネットワーク ケーブルを抜くと、「オンライン」イベントとプロパティが自動的に起動します。

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

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

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

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

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

この Mozilla Developer 記事の「メモ」セクションには、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, -- チャド

于 2012-03-13T02:19:54.057 に答える
15

最近で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ました。

ソース:カニウス

于 2016-04-01T11:04:21.657 に答える
13

@Juntoが言ったように、属性とそれに関連するイベントは現在、特定のWebブラウザー(特にFirefoxデスクトップ)では信頼できないため、ネットワーク接続ステータスを定期的にチェックし、適切なイベントを発生させる小さな関数(jQueryを使用)を作成window.navigator.onLineましofflineonline

// Global variable somewhere in your app to replicate the 
// window.navigator.onLine variable (this last 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');
  }
});
于 2015-02-17T09:11:15.797 に答える
7

navigator.onLine はめちゃくちゃです

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

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

  • ajax 呼び出しがタイムアウトし、エラーが発生する
  • ajax 呼び出しは成功を返しますが、メッセージは 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);
          }
        });
      }
于 2011-06-22T02:25:09.390 に答える
5

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

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

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

これがあなたが探しているものかどうかお知らせください。

敬具、

于 2010-07-05T16:59:09.777 に答える
3

私が Offline 用に書いた 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 を使用してクライアントがオフラインであることを検出するコード サンプルが含まれています。

于 2014-04-15T11:48:48.730 に答える
3

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

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

解決策の核心は、接続できない場合はドメイン名に接続してみてください - あなたはオフラインです. クロスブラウザで動作します。

于 2015-04-22T09:24:17.057 に答える
2

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

FALLBACK:
/online.txt /offline.txt

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

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

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

于 2016-03-08T15:46:22.877 に答える
0

これが私の解決策です。

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'; ?> 
于 2014-09-30T09:50:40.770 に答える