앱이 온라인 상태입니까? JS 10줄로 확실하게 아는 방법 [가이드]

우리는 일반적으로 웹 앱이 온라인에 있기를 기대하지만 현실을 무시합니다.

사람들은 비행기를 타거나, 터널에 들어가거나, 인터넷 상태가 좋지 않거나, 그냥 오프라인으로 가기로 결정합니다. 사용자의 기대에 따라 앱이 작동을 중지해야 합니까?

그렇지 않은 경우 적절한 경험을 제공하기 위해 앱이 오프라인인지 감지할 수 있는 안정적인 방법이 필요합니다.

다음은 JS의 10줄로 된 방법입니다.

TL;DR 코드는 복사/붙여넣기의 즐거움을 위해 맨 아래에 있습니다!

브라우저 탐색기



코딩하기 전에 토지의 위치를 ​​살펴보겠습니다.

브라우저에는 navigator.onLine 속성이 있습니다. 이것은 브라우저 상태에 따라 true 또는 false를 반환합니다.

function isOnline () {
    return window.navigator.onLine
}


우리는 끝났습니까? 글쎄, 작동 방식 때문에 오프라인을 의미하는 것으로만 false 신뢰할 수 있습니다. true 더 다양할 수 있습니다.

MDN - Navigator.onLine

그렇다면 인터넷에도 액세스할 수 있는지 어떻게 알 수 있습니까?



내비게이터가 작동하는 방식 때문에 오프라인일 때는 알지만 온라인 상태는 약간 흐릿합니다.

네비게이터는 장치가 네트워크에 연결되어 있을 때 true를 반환하지만 이는 두 가지 매우 다른 인터넷에도 연결되어 있음을 의미하지는 않습니다.

첫 번째 본능은 임의의 사이트에 요청을 하고 성공 또는 오류가 발생하는지 확인하는 것일 수 있습니다.

그러나 어떤 종류의 요청입니까? 그리고 어떤 자원에? 🤔

완벽한 요청 보내기 ✨



네트워크 상태 확인은 자주 발생할 수 있으므로 이상적으로는 요청 응답이 가능한 한 작아야 합니다. 이렇게 하면 속도가 빨라지고 대역폭이 덜 소모됩니다.

어떤 종류의 요청을 사용할 수 있는지 파악하기 위해 다양한 HTTP 메서드를 살펴보고 HEAD 메서드가 가장 우수합니다(TRACE가 실제로 더 나을 수 있지만 가져오기에서 지원되지 않음).

HEAD 요청은 응답 데이터가 없고 HEADer만 받는다는 점을 제외하면 GET 요청과 거의 동일합니다. 요청이 성공했는지 여부를 확인하는 것이 목표이므로 반환되는 데이터에 대해서는 신경 쓰지 않습니다.

요청을 어디로 보내야 합니까?



완벽한 요청이 있지만 어디로 가야 할까요?

첫 번째 본능은 항상 활성 상태인 서비스나 사이트로 보내는 것일 수 있습니다. 아마도 google.com? 그러나 시도하면 CORS 오류가 발생합니다.

이것은 의미가 있습니다. Google(및 기본적으로 다른 모든 사이트)은 임의 사이트의 요청을 수락하지 않습니다.
다음 옵션은 애플리케이션의 요청을 독점적으로 수락하는 자체 서버 또는 클라우드 기능을 만드는 것입니다!

그러나 그것은 단순한 네트워크 검사를 하기에는 너무 많은 작업이며 좋은 개발자는 게으른 개발자입니다.

다시 1번으로 돌아가서 CORS 오류입니다.

그들의 목표는 다른 출처에서 오는 요청에 대한 보안 문제를 방지하는 것입니다. 그러면 요청을 자신의 출처로 보낼 수 없습니까?

대답은 예입니다! 그리고 window.location.origin 를 사용하여 자동으로 원점을 얻을 수 있습니다.

async function isOnline () {
  if (!window.navigator.onLine) return false

  const response = await fetch(
    window.location.origin,
    { method: 'HEAD' },
  )

  return response.ok
}


이제 자신의 사이트를 ping하고 응답을 기다릴 수 있지만 문제는 우리가 항상 동일한 요청을 동일한 URL로 보내기 때문에 브라우저가 결과를 캐싱하는 데 시간을 낭비하지 않아 우리의 기능을 쓸모 없게 만듭니다.

따라서 마지막 트릭은 무작위 쿼리 매개변수를 사용하여 요청을 보내는 것입니다!
이것은 결과에 영향을 미치지 않으며 매번 다른 URL로 이동하기 때문에 브라우저가 응답을 캐싱하는 것을 방지합니다.

내장된 URL 클래스 덕분에 문자열을 수동으로 조작할 필요조차 없습니다.

다음은 추가 오류 처리와 함께 최종 코드입니다.

getRandomString () {
  return Math.random().toString(36).substring(2, 15)
}

async function isOnline () {
  if (!window.navigator.onLine) return false

  // avoid CORS errors with a request to your own origin
  const url = new URL(window.location.origin)

  // random value to prevent cached responses
  url.searchParams.set('rand', getRandomString())

  try {
    const response = await fetch(
      url.toString(),
      { method: 'HEAD' },
    )

    return response.ok
  } catch {
    return false
  }
}


이렇게 하면 네트워크 상태를 보다 안정적으로 확인할 수 있지만 일부 구성 옵션이 누락되었습니다.

특히 우리는 항상 동일한 URL로 확인합니다. 이것은 괜찮을 수 있지만 대기 시간을 줄이기 위해 자체 서버를 ping하거나 더 가까운 것을 선호한다면 어떻게 하시겠습니까?

또한 이것은 호출 시에만 실행되며 콜백을 전달하거나 일종의 관찰자가 있으면 유용할 수 있습니다.

네트워크 상태가 변경되면 이벤트 리스너를 얻습니다...

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


여기의 최종 결과는 매우 간단하며 이를 필요에 맞게 확장하는 것은 사용자의 몫입니다!


이 기사를 읽어 주셔서 감사합니다! 당신의 생각을 댓글로 알려주거나 트위터로 직접 메시지를 보내주세요.

좋은 웹페이지 즐겨찾기