12k
All articles

Как определить статус онлайн и офлайн в JavaScript

Определяйте онлайн и офлайн статус в JavaScript с navigator.onLine, событиями online/offline и проверкой связи через fetch.

OpenReplay Team
OpenReplay Team
Как определить статус онлайн и офлайн в JavaScript

Ваше приложение выглядит отлично — пока пользователь не потеряет соединение в середине сеанса, и ничего не начнет работать. Определение статуса онлайн и офлайн в JavaScript позволяет корректно реагировать на такие ситуации: показывать предупреждающий баннер, приостанавливать сетевые запросы или автоматически повторять попытки при восстановлении соединения. Вот как это сделать надежно.

Ключевые выводы

  • Используйте navigator.onLine для проверки статуса подключения при загрузке страницы и события online/offline объекта window для реакции на изменения в реальном времени.
  • Значение true в navigator.onLine не гарантирует фактический доступ к интернету — оно лишь подтверждает, что устройство подключено к какой-либо сети.
  • Проверяйте реальное подключение с помощью легковесного fetch-запроса к вашему собственному бэкенду перед возобновлением критических операций.
  • Комбинируйте все три подхода для надежной, готовой к продакшену обработки офлайн-режима.

Быстрый ответ: navigator.onLine и события Window

Браузер предоставляет два инструмента для определения статуса онлайн/офлайн в JavaScript:

  • navigator.onLine — булево свойство, которое можно прочитать в любой момент
  • события online и offline объекта window — срабатывают при изменении статуса подключения

Вместе они охватывают два сценария, которые вас интересуют: проверка статуса при загрузке страницы и реакция на его изменение.

Чтение navigator.onLine при загрузке страницы

if (navigator.onLine) {
  console.log('Browser reports online')
} else {
  console.log('Browser reports offline')
}

Это полезно для установки начального состояния UI при первой загрузке страницы — например, для отключения кнопки «Синхронизация», если пользователь уже находится в офлайн-режиме.

Прослушивание событий Online и Offline в JavaScript

Опрос navigator.onLine по таймеру расточителен. Вместо этого используйте события online и offline объекта window:

window.addEventListener('online', () => {
  console.log('Connection restored')
  // Re-enable UI, retry pending requests
})

window.addEventListener('offline', () => {
  console.log('Connection lost')
  // Show offline banner, disable network actions
})

Эти события срабатывают автоматически, когда браузер обнаруживает изменение статуса сети, поэтому ваше приложение реагирует немедленно без какого-либо опроса.

Практический пример: отображение баннера офлайн-режима

Вот минималистичный, готовый к продакшену паттерн, который объединяет оба подхода:

const banner = document.getElementById('offline-banner')

function updateOnlineStatus() {
  banner.hidden = navigator.onLine
}

// Set initial state
updateOnlineStatus()

// React to changes
window.addEventListener('online', updateOnlineStatus)
window.addEventListener('offline', updateOnlineStatus)
<div id="offline-banner" hidden>
  You're offline. Some features may be unavailable.
</div>

Этот паттерн чистый, событийно-ориентированный и избегает утечек памяти, поскольку обработчики подключаются один раз и повторно используют одну и ту же функцию-обработчик.

Критическое ограничение navigator.onLine

Это та часть, которую большинство руководств недостаточно объясняют. navigator.onLine не подтверждает фактический доступ к интернету.

  • false надежно — браузер определенно находится в офлайн-режиме.
  • true означает только то, что устройство подключено к какой-то сети (маршрутизатору, VPN-адаптеру, локальной сети). Пользователь может находиться за captive-порталом, или ваш бэкенд может быть недоступен.

Не доверяйте значению true в navigator.onLine как доказательству подключения. Используйте его как подсказку, что пользователь может быть офлайн, а не для подтверждения, что он подключен.

Проверка реального подключения с помощью сетевого запроса

Когда navigator.onLine возвращает true, но критическая операция завершается неудачей, подтвердите доступность с помощью легковесного запроса к вашему собственному бэкенду:

async function isReachable() {
  try {
    const response = await fetch('/health-check', {
      method: 'HEAD',
      cache: 'no-store',
    })
    return response.ok
  } catch {
    return false
  }
}

Используйте свой собственный эндпоинт — не сторонний URL — чтобы избежать проблем с CORS. Запрос HEAD к небольшому, быстрому маршруту минимизирует влияние на трафик.

Опционально: Network Information API

Для получения информации о качестве соединения (не только онлайн/офлайн), navigator.connection предоставляет такие свойства, как effectiveType ('4g', '3g', 'slow-2g') и downlink. Поддержка браузерами ограничена браузерами на базе Chromium — рассматривайте это только как прогрессивное улучшение.

Тестирование офлайн-поведения в DevTools

Откройте Chrome DevTools → вкладка Network → установите выпадающий список throttle на Offline. Это вызовет событие offline и установит navigator.onLine в false, позволяя вам тестировать UI без отключения вашей машины от сети.

Заключение

Определение статуса онлайн в JavaScript сводится к трем вещам: чтение navigator.onLine при загрузке, прослушивание событий online/offline для отслеживания изменений и проверка реального подключения с помощью fetch-запроса перед возобновлением критических операций. Эта комбинация чисто и эффективно обрабатывает подавляющее большинство реальных сценариев подключения.

Часто задаваемые вопросы

Могу ли я использовать navigator.onLine для подтверждения доступа пользователя к интернету?

Нет. Значение true в navigator.onLine означает только то, что устройство подключено к какой-то сети, например к маршрутизатору или VPN-адаптеру. Это не гарантирует фактический доступ к интернету. Пользователь может находиться за captive-порталом, или ваш сервер может быть недоступен. Всегда проверяйте с помощью реального сетевого запроса для критических операций.

Работают ли события online и offline во всех основных браузерах?

Да. События online и offline объекта window и свойство navigator.onLine поддерживаются во всех современных браузерах, включая Chrome, Firefox, Safari и Edge. Они являются частью спецификации HTML и имеют широкую поддержку уже много лет.

Как мне проверить реальное подключение в продакшен-приложении?

Отправьте легковесный fetch-запрос, например HEAD-запрос, к эндпоинту проверки работоспособности на вашем собственном сервере. Используйте cache no-store для обхода кэша браузера. Если запрос успешен и возвращает статус ok, у пользователя есть подлинное подключение. Избегайте пинга сторонних URL, чтобы предотвратить проблемы с CORS.

Надежен ли Network Information API для определения качества соединения?

Network Information API предоставляет полезные подсказки, такие как эффективный тип соединения и скорость загрузки, но поддержка браузерами ограничена браузерами на базе Chromium. Safari и Firefox не поддерживают его. Рассматривайте его как прогрессивное улучшение и всегда предоставляйте резервное поведение для неподдерживаемых браузеров.

Open-source session replay

Complete picture for complete understanding

Capture every clue your frontend is leaving so you can instantly get to the root cause of any issue with OpenReplay — the open-source session replay tool for developers. Self-host it in minutes, and have complete control over your customer data.

Star on GitHub12k

We use cookies to improve your experience. By using our site, you accept cookies.