PCブラウザでネットワーク接続の有無を検知するには?
PCブラウザでネットワーク接続の有無を検知するにはどうしたらいいだろう?
一応「navigator.onLine」というAPIはある。
window.navigator.onLine - Web API インターフェイス | MDN
ブラウザのサポート具合を調べてみると、全てのブラウザというわけにはいかないが、まあまあサポートされていることがわかる。
Can I use... Support tables for HTML5, CSS3, etc
しかし、このAPIには色々と問題があることがすぐに分かった。
javascript - How to detect online/offline event cross-browser? - Stack Overflow
要するに、ChromeやSafariならネットワーク接続が切れた時点で自動的にオフラインイベントが来るが、FirefoxやOpera、IEはブラウザ側に「オフラインモード」という機能があるので、navigator.onLineの値は実際のネットワーク接続に有無ではなく「オフラインモードかどうか」の値になってしまう、という話。
つまり、全くもって役に立たない!
ではどうするか?
StackOverflowでも議論されているが、要するに「サーバーにリクエストを投げて返ってくればオンラインじゃね?」というシンプルな考え方が最も信頼できそうだ。
賢くやりたいなら、こういったライブラリもある。
cvan/navigator.onLine-that-actually-works
愚直にやりたいなら、ここが参考になる。シンプルにXMLHttpRequestを使う。
navigator.onLine alternative: serverReachable() | Louis-Rémi
このコードを参考に、少し改造してこのようにした。
req.open()でのメソッドの指定はHEADにした方が高速化のためには好ましいのだろうが、ローカルのデバッグサーバーによっては著しくレスポンスが遅い場合があった。
そこで、サーバー上にゼロバイトのHTMLファイルを作り、HEADではなくGETを指定してそのファイルのURLを指定するようにした。恐らくこの方法は鉄板だと思われる。
一応「navigator.onLine」というAPIはある。
window.navigator.onLine - Web API インターフェイス | MDN
ブラウザのサポート具合を調べてみると、全てのブラウザというわけにはいかないが、まあまあサポートされていることがわかる。
Can I use... Support tables for HTML5, CSS3, etc
しかし、このAPIには色々と問題があることがすぐに分かった。
javascript - How to detect online/offline event cross-browser? - Stack Overflow
…
Chrome and Safari will detect when you go "offline" automatically - meaning that "online" events and properties will fire automatically when you unplug your network cable.
Firefox (Mozilla), Opera, and IE take a different approach, and consider you "online" unless you explicitly pick "Offline Mode" in the browser - even if you don't have a working network connection.
…
要するに、ChromeやSafariならネットワーク接続が切れた時点で自動的にオフラインイベントが来るが、FirefoxやOpera、IEはブラウザ側に「オフラインモード」という機能があるので、navigator.onLineの値は実際のネットワーク接続に有無ではなく「オフラインモードかどうか」の値になってしまう、という話。
つまり、全くもって役に立たない!
ではどうするか?
StackOverflowでも議論されているが、要するに「サーバーにリクエストを投げて返ってくればオンラインじゃね?」というシンプルな考え方が最も信頼できそうだ。
賢くやりたいなら、こういったライブラリもある。
cvan/navigator.onLine-that-actually-works
愚直にやりたいなら、ここが参考になる。シンプルにXMLHttpRequestを使う。
navigator.onLine alternative: serverReachable() | Louis-Rémi
このコードを参考に、少し改造してこのようにした。
/** * 実際にサーバーに接続できるかどうかを返す * URL指定が無ければ自ホストの「/? + Math.random()」 */ function isServerReachable(url) { if (!url) { url = location.protocol + '//' + location.host + '/?' + Math.random(); } console.log('ネットワーク接続を確認します:' + url); try { var req = new XMLHttpRequest(); req.open("GET", url, false); //同期で接続 req.send(); if ((200 <= req.status && req.status < 300) || req.status == 304) { console.log('ネットワーク接続可能 status=' + req.status + '(' + req.statusText + ')'); return true; } else { console.log('ネットワーク接続エラー status=' + req.status + '(' + req.statusText + ')'); return false; } } catch (err) { console.log('ネットワーク接続エラー'); return false; } }
req.open()でのメソッドの指定はHEADにした方が高速化のためには好ましいのだろうが、ローカルのデバッグサーバーによっては著しくレスポンスが遅い場合があった。
そこで、サーバー上にゼロバイトのHTMLファイルを作り、HEADではなくGETを指定してそのファイルのURLを指定するようにした。恐らくこの方法は鉄板だと思われる。
コメント
コメントを投稿