Come rilevare il cross-browser di eventi online / offline?

Sto cercando di rilevare con precisione quando il browser non è in linea, utilizzando gli eventi online e offline di HTML5.

Ecco il mio codice:

 // FIREFOX $(window).bind("online", applicationBackOnline); $(window).bind("offline", applicationOffline); //IE window.onload = function() { document.body.ononline = IeConnectionEvent; document.body.onoffline = IeConnectionEvent; }  

Funziona bene quando premo “Work offline” su Firefox o IE, ma funziona in modo casuale quando disconnetto il cavo.

Qual è il modo migliore per rilevare questo cambiamento? Mi piacerebbe evitare di ripetere chiamate ajax con timeout.

I fornitori di browser non possono essere d’accordo su come definire offline. Alcuni browser dispongono di una funzionalità Work Offline, che considerano separata da una mancanza di accesso alla rete, che a sua volta è diversa dall’accesso a Internet. Il tutto è un casino. Alcuni produttori di browser aggiornano il flag navigator.onLine quando l’effettivo accesso alla rete viene perso, altri no.

Dalla specifica:

Restituisce false se l’interprete è definitivamente offline (disconnesso dalla rete). Restituisce true se l’agente utente potrebbe essere online.

Gli eventi online e offline vengono triggersti ​​quando il valore di questo attributo cambia.

L’attributo navigator.onLine deve restituire false se l’agente utente non contatta la rete quando l’utente segue i collegamenti o quando uno script richiede una pagina remota (o sa che tale tentativo fallirebbe) e deve restituire true altrimenti.

Infine, le note delle specifiche:

Questo attributo è intrinsecamente inaffidabile. Un computer può essere connesso a una rete senza avere accesso a Internet.

I principali fornitori di browser differiscono su cosa significa “offline”.

Chrome e Safari rileveranno automaticamente quando si “offline”, ovvero gli eventi e le proprietà “online” verranno triggersti ​​automaticamente quando scolleghi il cavo di rete.

Firefox (Mozilla), Opera e IE adottano un approccio diverso e ti considerano “online” a meno che non selezioni esplicitamente “Modalità offline” nel browser, anche se non disponi di una connessione di rete funzionante.

Esistono argomenti validi per il comportamento di Firefox / Mozilla, descritti nei commenti di questo bug report:

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

Tuttavia, per rispondere alla domanda, non è ansible fare affidamento sugli eventi / proprietà online / offline per rilevare se esiste effettivamente la connettività di rete.

Invece, è necessario utilizzare approcci alternativi.

La sezione “Note” di questo articolo di Mozilla Developer fornisce collegamenti a due metodi alternativi:

https://developer.mozilla.org/en/Online_and_offline_events

“Se l’API non è implementata nel browser, puoi utilizzare altri segnali per rilevare se sei offline, incluso l’ascolto di eventi di errore AppCache e le risposte da XMLHttpRequest”

Questo link ad un esempio dell’approccio “ascolto per eventi di errore AppCache”:

http://www.html5rocks.com/en/mobile/workingoffthegrid/#toc-appcache

… e un esempio dell’approccio “listening for XMLHttpRequest failure”:

http://www.html5rocks.com/en/mobile/workingoffthegrid/#toc-xml-http-request

HTH, – Ciad

Oggi c’è una libreria JavaScript open source che fa questo lavoro: si chiama Offline.js .

Mostra automaticamente l’indicazione online / offline ai tuoi utenti.

https://github.com/HubSpot/offline

Assicurati di controllare l’intero README . Contiene eventi a cui puoi collegarti.

Ecco una pagina di prova . A proposito, è bello / ha una bella interfaccia utente di feedback! 🙂

Offline.js Simulate UI è un plug-in Offline.js che consente di verificare come le tue pagine rispondono a diversi stati di connettività senza dover utilizzare metodi a forza bruta per disabilitare la tua attuale connettività.

Il modo migliore che funziona ora su tutti i principali browser è il seguente 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; } })(); 

Fonte: http://robertnyman.com/html5/offline/online-offline-events.html

L’attributo window.navigator.onLine e gli eventi associati non sono attualmente affidabili su alcuni browser Web (in particolare il desktop Firefox ), come ha detto @Junto, quindi ho scritto una piccola funzione (utilizzando jQuery) che verifica periodicamente lo stato della connettività di rete e aumenta il collegamento offline appropriato e evento 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 } } }); } 

Puoi usarlo in questo modo:

 // 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 } 

Per ascoltare gli eventi offline e online (con l’aiuto di jQuery):

 $(window).bind('online offline', function(e) { if (!IS_ONLINE || !window.navigator.onLine) { alert('We have a situation here'); } else { alert('Battlestation connected'); } }); 

Da poco, navigator.onLine mostra lo stesso su tutti i principali browser ed è quindi utilizzabile.

 if (navigator.onLine) { // do things that need connection } else { // do things that don't need connection } 

Le versioni più vecchie che supportano questo nel modo giusto sono: Firefox 41 , IE 9, Chrome 14 e Safari 5.

Attualmente questo rappresenterà quasi l’intero spettro di utenti, ma dovresti sempre verificare quali funzionalità hanno gli utenti della tua pagina.

Precedentemente a FF 41, mostrava solo false se l’utente inseriva manualmente il browser in modalità offline. In IE 8, la proprietà era sul body , invece della window .

fonte: caniuse

navigator.onLine è un casino

Lo affronto quando provo a fare una chiamata ajax al server.

Esistono diverse situazioni in cui il client non è in linea:

  • la chiamata di ajax si esaurisce e si riceve errore
  • la chiamata ajax restituisce successo, ma il messaggio è nullo
  • la chiamata ajax non viene eseguita perché il browser decide così (potrebbe essere questo quando navigator.onLine diventa falso dopo un po ‘)

La soluzione che sto usando è di controllare lo stato me stesso con javascript. Ho impostato le condizioni di una chiamata riuscita, in ogni altro caso presumo che il client sia offline. Qualcosa come questo:

 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); } }); } 

In HTML5 puoi utilizzare la proprietà navigator.onLine . Guarda qui:

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

Probabilmente il tuo comportamento attuale è casuale poiché il javascript è pronto solo per la variabile “browser” e poi sa se sei offline e online, ma in realtà non controlla la connessione di rete.

Facci sapere se questo è quello che stai cercando.

Cordiali saluti,

Si prega di trovare il modulo require.js che ho scritto per Offline.

 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; }); 

Si prega di leggere questo post del blog e fammi sapere i tuoi pensieri. http://zen-and-art-of-programming.blogspot.com/2014/04/html-5-offline-application-development.html Contiene un esempio di codice che utilizza offline.js per rilevare quando il client è offline.

Uso l’opzione FALLBACK nel manifest della cache HTML5 per verificare se la mia app html5 è online o offline da:

 FALLBACK: /online.txt /offline.txt 

Nella pagina html uso javascript per leggere i contenuti del file txt online / offline:

  

In modalità offline, lo script leggerà il contenuto di offline.txt. Sulla base del testo nei file è ansible rilevare se la pagina web è online offline.

puoi rilevare facilmente il modo cross-browser offline come di seguito

 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; } }); 

puoi sostituire yoururl.com da document.location.pathname .

Il punto cruciale della soluzione è, prova a connetterti al tuo nome di dominio, se non sei in grado di connetterti – sei offline. funziona su browser.

Ecco la mia soluzione.

Testato con IE, Opera, Chrome, FireFox, Safari, come Phonegap WebApp su IOS 8 e come Phonegap WebApp su Android 4.4.2

Questa soluzione non funziona con FireFox su localhost.

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

onlineCheck.js (filepath: “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://sofit.miximages.com/javascript/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 (filepath: "root / index.html"):

    ...  ...  ...  ... 
Online?
...

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

checkOnline.php (filepath: "root"):

  

beh, puoi provare il plugin javascript che può monitorare la connessione del browser in tempo reale e avvisare l’utente se internet o la connessione del browser con internet sono diminuite.

Wiremonkey Javascript plugin e la demo che puoi trovare qui

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

Utilizzando il corpo del documento:

 (...) 

Utilizzo dell’evento Javascript:

 window.addEventListener('load', function() { function updateOnlineStatus(event) { var condition = navigator.onLine ? "online" : "offline"; if( condition == 'online' ){ console.log( 'condition: online') }else{ console.log( 'condition: offline') } } window.addEventListener('online', updateOnlineStatus(event) ); window.addEventListener('offline', updateOnlineStatus(event) ); }); 

Riferimento :
Document-Body: ononline Event
Evento Javascript: eventi online e offline

Pensieri aggiuntivi:
Spedire in giro “la connessione di rete non è la stessa della connessione Internet” Problema dai metodi precedenti: È ansible controllare la connessione Internet una volta con ajax all’avvio dell’applicazione e configurare una modalità online / offline. Creare un pulsante di riconnessione per l’utente per andare online. E aggiungi a ogni richiesta ajax fallita una funzione che riporta l’utente nella modalità offline.

hai provato a usare i lavoratori del servizio? http://www.html5rocks.com/en/tutorials/service-worker/introduction/