web-dev-qa-db-ja.com

インターネット接続がオフラインであることを検出しますか?

JavaScriptでインターネット接続がオフラインであることを検出する方法は?

198
Daniel Silveira

失敗したXHR要求を行うことにより、接続が失われたことを確認できます。

標準的なアプローチは、リクエストを再試行するを数回行うことです。通過しない場合は、ユーザーに警告するで接続を確認し、正常に失敗するにします。

補足:アプリケーション全体を「オフライン」状態にすると、多くのエラーが発生しやすい状態の処理が行われる可能性があります。無線接続が行き来する可能性があります。正常に失敗し、データを保存し、ユーザーに警告します。接続の問題があればそれを最終的に修正し、かなりの許しでアプリを使用し続けることができます。

補足: googleのような信頼性の高いサイトで接続を確認できますが、これは単に独自のリクエストを試みることとしては完全に役立つとは限りません。そして、あなたはまだあなた自身の接続問題を処理しなければなりません。 googleにpingを送信することは、インターネット接続自体がダウンしていることを確認するための良い方法です。そのため、その情報が役立つ場合は、トラブルに見合う価値があるかもしれません。

サイドノートPingの送信は、あらゆる種類の双方向Ajaxリクエストを行うのと同じ方法で実現できますが、ただし、この場合pingをgoogleに送信すると、いくつかの課題が生じます。まず、Ajax通信を行う際に通常発生するクロスドメインの問題があります。 1つのオプションは、サーバー側プロキシを設定することです。ここでは、実際にping google(または任意のサイト)を実行し、pingの結果をアプリに返します。これはcatch-22です。これは、インターネット接続が実際に問題である場合、サーバーにアクセスできず、接続の問題が自分のドメインのみにある場合、違いを見分けることができる。他のクロスドメイン手法、たとえば、google.comを指すiframeをページに埋め込み、成功/失敗についてiframeをポーリングする(コンテンツを調べるなど)こともできます。何が起こっているのかについての良い結論を引き出すために、コミュニケーションメカニズムからの有用な応答が必要なため、画像を埋め込むことは実際には何も教えてくれません。繰り返しになりますが、インターネット接続の状態を全体として判断することは、それが価値がある以上に面倒な場合があります。特定のアプリについては、これらのオプションに重みを付ける必要があります。

124
keparo

IE 8は window.navigator.onLine プロパティをサポートします。

しかし、もちろん、それは他のブラウザーやオペレーティングシステムには役立ちません。他のブラウザベンダーは、Ajaxアプリケーションのオンライン/オフラインステータスを知ることの重要性を考慮して、そのプロパティを提供することを決定すると予測しています。

それが起こるまで、XHRまたはImage()または<img>要求のいずれかが、必要な機能に近いものを提供できます。

更新(2014/11/16)

現在、主要なブラウザはこのプロパティをサポートしていますが、結果は異なります。

Mozillaドキュメント からの引用:

ChromeおよびSafariでは、ブラウザーがローカルエリアネットワーク(LAN)またはルーターに接続できない場合、オフラインになります。他のすべての条件はtrueを返します。したがって、ブラウザがfalse値を返すときにブラウザがオフラインであると想定できますが、真の値がブラウザがインターネットにアクセスできることを必ずしも意味すると想定することはできません。常に「接続」されている仮想イーサネットアダプターを備えた仮想化ソフトウェアをコンピューターが実行している場合など、誤検知が発生する可能性があります。したがって、ブラウザのオンラインステータスを本当に確認したい場合は、追加のチェック手段を開発する必要があります。

FirefoxおよびInternet Explorerでは、ブラウザーをオフラインモードに切り替えると、false値が送信されます。他のすべての条件は、true値を返します。

46
Grant Wagner

これを行うには、いくつかの方法があります。

  • あなた自身のウェブサイトへのAJAXリクエスト。その要求が失敗した場合、障害のある接続である可能性が高くなります。 JQuery ドキュメントには handling failed AJAX requests に関するセクションがあります。 Same Origin Policy に注意してください。これにより、ドメイン外のサイトにアクセスできなくなる場合があります。
  • 次のようにonerrorimgを入れることができます

    <img src='http://www.example.com/singlepixel.gif' 
          onerror='alert("Connection dead");' />
    

    この方法は、ソースイメージが移動/名前変更された場合にも失敗する可能性があり、通常はajaxオプションよりも劣る選択肢です。

そのため、これを試して検出する方法はいくつかありますが、完璧ではありませんが、ブラウザのサンドボックスから飛び出し、ユーザーのネット接続ステータスに直接アクセスする機能がない場合、それらが最良のオプションのようです。

33
ConroyP
 if(navigator.onLine){
  alert('online');
 } else {
  alert('offline');
 }
30
Edmhs

ほぼすべての主要ブラウザwindow.navigator.onLine プロパティと、対応するonlineおよびofflineウィンドウイベントをサポートするようになりました。

window.addEventListener('online', () => console.log('came online'));
window.addEventListener('offline', () => console.log('came offline'));

システムまたはブラウザをオフライン/オンラインモードに設定して、コンソールまたはwindow.navigator.onLineプロパティで値の変更を確認してください。 このWebサイト でもテストできます。

ただし、 Mozilla Documentation からのこの引用に注意してください。

ChromeおよびSafariでは、ブラウザーがローカルエリアネットワーク(LAN)またはルーターに接続できない場合、オフラインになります。他のすべての条件はtrueを返します。したがって、ブラウザがfalse値を返すときにオフラインであると想定できますがtrueと想定することはできません値は必然的にブラウザがインターネットにアクセスできることを意味します。常に「接続」されている仮想イーサネットアダプターを備えた仮想化ソフトウェアをコンピューターが実行している場合など、誤検知が発生する可能性があります。したがって、ブラウザのオンラインステータスを本当に確認したい場合は、追加のチェック手段を開発する必要があります。

FirefoxおよびInternet Explorerでは、ブラウザーをオフラインモードに切り替えると、false値が送信されます。 Firefox 41まで、他のすべての条件はtrue値を返します。 Firefox 41以降、OS XおよびWindowsでは、値は実際のネットワーク接続に従います。

(強調は私自身です)

これは、window.navigator.onLinefalseである場合(またはofflineイベントを取得する場合)、インターネット接続がないことが保証されることを意味します。

ただし、trueである場合(またはonlineイベントを取得する場合)は、せいぜいシステムが何らかのネットワークに接続されていることを意味します。たとえば、インターネットにアクセスできるという意味ではありません。それを確認するには、他の回答で説明されているソリューションのいずれかを使用する必要があります。

私は当初これを Grant Wagnerの回答 の更新として投稿するつもりでしたが、特に2014年の更新が既に 彼からではない であることを考えると、編集が多すぎるように思われました。

14
Didier L

HTML5 Application Cache APIはnavigator.onLineを指定します。これは現在IE8ベータ版、WebKit(例:Safari)ナイトリーで利用可能で、Firefox 3で既にサポートされています

11
olliej

Olliejが言ったように、navigator.onLine browserプロパティを使用することは、ネットワーク要求を送信するよりも望ましいため、 developer.mozilla.org/En/Online_and_offline_events を使用すると、古いバージョンのFirefoxおよびIEでもサポートされます。

最近、WHATWGは、navigator.onLineの変更に対応する必要がある場合に、onlineおよびofflineイベントの追加を指定しました。

また、Daniel Silveiraが投稿したリンクにも注意してください。サーバーとの同期をこれらの信号/プロパティに依存することは必ずしも良い考えではありません。

9
Emanuele Aina

$。ajax()errorコールバックを使用できます。これは、リクエストが失敗した場合に起動します。 textStatusがストリング「timeout」と等しい場合、おそらく接続が切断されていることを意味します。

function (XMLHttpRequest, textStatus, errorThrown) {
  // typically only one of textStatus or errorThrown 
  // will have info
  this; // the options for this ajax request
}

doc から:

Error:要求が失敗した場合に呼び出される関数。関数には3つの引数が渡されます。XMLHttpRequestオブジェクト、発生したエラーの種類を説明する文字列、およびオプションの例外オブジェクト(発生した場合)。 2番目の引数(null以外)に可能な値は、「timeout」、「error」、「notmodified」、および「parsererror」です。これはAjaxイベントです

たとえば、次のとおりです。

 $.ajax({
   type: "GET",
   url: "keepalive.php",
   success: function(msg){
     alert("Connection active!")
   },
   error: function(XMLHttpRequest, textStatus, errorThrown) {
       if(textStatus == 'timeout') {
           alert('Connection seems dead!');
       }
   }
 });
8
karim79

ドメインへのajax呼び出しは、オフラインかどうかを検出する最も簡単な方法です

$.ajax({
      type: "HEAD",
      url: document.location.pathname + "?param=" + new Date(),
      error: function() { return false; },
      success: function() { return true; }
   });

これは単に概念を提供するためのものであり、改善する必要があり、HTTPステータスコードなどを確認してください

5
harishr

学校でよく働く顧客のためにWebアプリ(ajaxベース)を作成する必要がありましたが、これらの学校ではインターネット接続が悪いことがよくあります。

CodeIgniterとJqueryを使用します。

    function checkOnline(){
    setTimeout("doOnlineCheck()", 20000);
}

function doOnlineCheck(){
    var submitURL = $("#base_path").val() + "index.php/menu/online";//if the server can be reached it returns 1, other wise it times out
    $.ajax({
        url     : submitURL     ,
        type    : 'post'        ,
        dataType: 'msg'         ,
        timeout : 5000          ,
        success : function(msg){
            if(msg==1){
                $("#online").addClass("online");
                $("#online").removeClass("offline");
            }else{
                $("#online").addClass("offline");
                $("#online").removeClass("online");
            }
            checkOnline();
        }   ,
        error   : function(){
            $("#online").addClass("offline");
            $("#online").removeClass("online");
            checkOnline();
        }
    });
}
4
THEO

とても簡単な方法だと思います。

var x = confirm("Are you sure you want to submit?");
if (x) {
  if (navigator.onLine == true) {
    return true;
  }
  alert('Internet connection is lost');
  return false;
}
return false;
4

インターネットがダウンしているか、サーバーがダウンしているかを検出するクライアント側のソリューションを探していました。私が見つけた他のソリューションは、常にサードパーティのスクリプトファイルまたはイメージに依存しているように見えましたが、それは時の試練に耐えられるとは思えませんでした。外部でホストされるスクリプトまたはイメージは将来変更され、検出コードが失敗する可能性があります。

404コードでxhrStatusを探すことでそれを検出する方法を見つけました。さらに、JSONPを使用してCORS制限をバイパスします。 404以外のステータスコードは、インターネット接続が機能していないことを示しています。

$.ajax({
    url:      'https://www.bing.com/aJyfYidjSlA' + new Date().getTime() + '.html',
    dataType: 'jsonp',
    timeout:  5000,

    error: function(xhr) {
        if (xhr.status == 404) {
            //internet connection working
        }
        else {
            //internet is down (xhr.status == 0)
        }
    }
});
1
wayofthefuture

2つの異なるシナリオについて、これに対する2つの答えがあります:

  1. JavaScriptをWebサイト(つまり、フロントエンド部分)で使用している場合、最も簡単な方法は次のとおりです。

    <h2>The Navigator Object</h2>
    
    <p>The onLine property returns true if the browser is online:</p>
    
    <p id="demo"></p>
    
    <script>
      document.getElementById("demo").innerHTML = "navigator.onLine is " + navigator.onLine;
    </script>
    
  2. ただし、サーバー側(ノードなど)でjsを使用している場合、失敗したXHRリクエストを行うことで接続が失われていると判断できます。

    標準的なアプローチは、リクエストを数回再試行することです。通過しない場合は、ユーザーに接続を確認するよう警告し、正常に失敗します。

0
Rishabh Anand

私のやり方。

<!-- the file named "tt.jpg" should exist in the same directory -->

<script>
function testConnection(callBack)
{
    document.getElementsByTagName('body')[0].innerHTML +=
        '<img id="testImage" style="display: none;" ' +
        'src="tt.jpg?' + Math.random() + '" ' +
        'onerror="testConnectionCallback(false);" ' +
        'onload="testConnectionCallback(true);">';

    testConnectionCallback = function(result){
        callBack(result);

        var element = document.getElementById('testImage');
        element.parentNode.removeChild(element);
    }    
}
</script>

<!-- usage example -->

<script>
function myCallBack(result)
{
    alert(result);
}
</script>

<a href=# onclick=testConnection(myCallBack);>Am I online?</a>
0
unxed

navigator.onLineのような一部のメソッドの問題は、一部のブラウザーおよびモバイルバージョンと互換性がないことです。これは、古典的なXMLHttpRequestメソッドを使用し、ファイルが保存される可能性のあるケース応答付きキャッシュXMLHttpRequest.statusは200を超え、304未満です。

ここに私のコード:

 var xhr = new XMLHttpRequest();
 //index.php is in my web
 xhr.open('HEAD', 'index.php', true);
 xhr.send();

 xhr.addEventListener("readystatechange", processRequest, false);

 function processRequest(e) {
     if (xhr.readyState == 4) {
         //If you use a cache storage manager (service worker), it is likely that the
         //index.php file will be available even without internet, so do the following validation
         if (xhr.status >= 200 && xhr.status < 304) {
             console.log('On line!');
         } else {
             console.log('Offline :(');
         }
     }
}
0

リクエストエラーのリクエストヘッド

$.ajax({
    url: /your_url,
    type: "POST or GET",
    data: your_data,
    success: function(result){
      //do stuff
    },
    error: function(xhr, status, error) {

      //detect if user is online and avoid the use of async
        $.ajax({
            type: "HEAD",
            url: document.location.pathname,
            error: function() { 
              //user is offline, do stuff
              console.log("you are offline"); 
              }
         });
    }   
});
0
Kareem