program tip

온라인 / 오프라인 이벤트 크로스 브라우저를 감지하는 방법은 무엇입니까?

radiobox 2020. 8. 12. 08:05
반응형

온라인 / 오프라인 이벤트 크로스 브라우저를 감지하는 방법은 무엇입니까?


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 호출을 피하고 싶습니다.


브라우저 공급 업체는 오프라인 정의 방법에 동의 할 수 없습니다. 일부 브라우저에는 오프라인 작업 기능이 있는데, 이는 네트워크 액세스 부족과 별개로 간주되며 인터넷 액세스와는 다릅니다. 모든 것이 엉망입니다. 일부 브라우저 공급 업체는 실제 네트워크 액세스가 손실 될 때 navigator.onLine 플래그를 업데이트하고 다른 공급 업체는 업데이트하지 않습니다.

사양에서 :

사용자 에이전트가 확실히 오프라인 (네트워크 연결이 끊김)이면 false를 반환합니다. 사용자 에이전트가 온라인 일 수있는 경우 true를 반환합니다.

이 속성 값이 변경되면 온라인 및 오프라인 이벤트가 시작됩니다.

navigator.onLine 속성은 사용자가 링크를 따를 때 또는 스크립트가 원격 페이지를 요청할 때 사용자 에이전트가 네트워크에 접속하지 않을 경우 (또는 그러한 시도가 실패 할 것이라는 것을 알고) false를 반환해야하며 그렇지 않으면 true를 반환해야합니다.

마지막으로 사양 노트 :

이 속성은 본질적으로 신뢰할 수 없습니다. 인터넷 액세스없이 컴퓨터를 네트워크에 연결할 수 있습니다.


주요 브라우저 공급 업체는 "오프라인"의 의미가 다릅니다.

Chrome 및 Safari는 사용자가 "오프라인"상태가되면 자동으로 감지합니다. 즉, 네트워크 케이블을 분리하면 "온라인"이벤트 및 속성이 자동으로 실행됩니다.

Firefox (Mozilla), Opera 및 IE는 다른 접근 방식을 취하며 브라우저에서 "오프라인 모드"를 명시 적으로 선택하지 않는 한 "온라인"으로 간주합니다. 네트워크 연결이 작동하지 않는 경우에도 마찬가지입니다.

Firefox / Mozilla 동작에 대한 유효한 인수가 있으며이 버그 보고서의 주석에 설명되어 있습니다.

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

그러나 질문에 답하기 위해 온라인 / 오프라인 이벤트 / 속성에 의존하여 실제로 네트워크 연결이 있는지 감지 할 수는 없습니다.

대신 대체 접근 방식을 사용해야합니다.

이 Mozilla 개발자 문서의 "참고"섹션에서는 두 가지 대체 방법에 대한 링크를 제공합니다.

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,-차드


오늘날이 작업을 수행하는 오픈 소스 JavaScript 라이브러리가 Offline.js있습니다.

사용자에게 온라인 / 오프라인 표시를 자동으로 표시합니다.

https://github.com/HubSpot/offline

전체 README 를 확인하십시오 . 연결할 수있는 이벤트가 포함되어 있습니다.

다음은 테스트 페이지 입니다. 그것은 아름답습니다 / 그나저나 멋진 피드백 UI가 있습니다! :)

Offline.js Simulate UI는 실제 연결을 비활성화하기 위해 무차별 대입 방법을 사용하지 않고도 페이지가 다른 연결 상태에 어떻게 반응하는지 테스트 할 수있는 Offline.js 플러그인입니다.


현재 모든 주요 브라우저에서 작동하는 가장 좋은 방법은 다음 스크립트입니다.

(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


window.navigator.onLine속성과 관련된 이벤트는 특정 웹 브라우저 (에 현재 신뢰할 특히 파이어 폭스 데스크톱 나는 주기적으로 네트워크 연결 상태를 확인하고 적절한 올릴 것을 (jQuery를 사용) 약간의 기능 썼다 있도록 @Junto 말한대로) offlineonline이벤트를 :

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

최근부터 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


navigator.onLine은 엉망입니다.

서버에 ajax 호출을 시도 할 때 이것을 직면합니다.

클라이언트가 오프라인 일 때 몇 가지 가능한 상황이 있습니다.

  • ajax 호출 시간 초과 및 오류 수신
  • ajax 호출은 성공을 반환하지만 msg는 null입니다.
  • 브라우저가 그렇게 결정했기 때문에 ajax 호출이 실행되지 않습니다 (잠시 후 navigator.onLine이 거짓이되는 경우 일 수 있음).

내가 사용하는 해결책은 자바 스크립트로 상태를 직접 제어하는 ​​것입니다. 나는 성공적인 호출의 조건을 설정했으며, 다른 경우에는 클라이언트가 오프라인이라고 가정합니다. 이 같은:

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

HTML5에서는 navigator.onLine속성을 사용할 수 있습니다 . 이봐:

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

아마도 현재 동작은 자바 스크립트가 "브라우저"변수 만 준비하고 오프라인 및 온라인 상태인지 알고 있지만 실제로 네트워크 연결을 확인하지 않기 때문에 임의적 일 것입니다.

이것이 당신이 찾고있는 것인지 알려주세요.

감사합니다.


오프라인 용으로 작성한 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를 사용하는 코드 샘플이 포함되어 있습니다.


아래와 같이 쉽게 오프라인 크로스 브라우저 방식을 감지 할 수 있습니다.

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.

솔루션의 핵심은 연결할 수없는 경우 도메인 이름에 연결을 시도하는 것입니다. 오프라인 상태입니다. 크로스 브라우저에서 작동합니다.


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의 내용을 읽습니다. 파일의 텍스트를 기반으로 웹 페이지가 오프라인 상태인지 감지 할 수 있습니다.


여기 내 해결책이 있습니다.

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 (파일 경로 : "root") :

<?php echo 'true'; ?> 

글쎄, 당신은 실시간으로 브라우저 연결을 모니터링하고 인터넷 또는 인터넷과의 브라우저 연결이 끊어지면 사용자에게 알리는 자바 스크립트 플러그인을 사용해 볼 수 있습니다.

여기에서 찾을 수있는 Wiremonkey Javascript 플러그인 및 데모

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


문서 본문 사용 :

<body ononline="onlineConditions()" onoffline="offlineConditions()">(...)</body>

자바 스크립트 이벤트 사용 :

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

});

Reference:
Document-Body: ononline Event
Javascript-Event: Online and offline events

Additional Thoughts:
To ship around the "network connection is not the same as internet connection" Problem from the above methods: You can check the internet connection once with ajax on the application start and configure an online/offline mode. Create a reconnect button for the user to go online. And add on each failed ajax request a function that kick the user back into the offline mode.

참고URL : https://stackoverflow.com/questions/3181080/how-to-detect-online-offline-event-cross-browser

반응형