Offline: примеры (JAVASCRIPT)

Работа с офлайн-режимом в JavaScript: руководство и практические примеры
Раздел: События, Сетевое подключение
offline: Event

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

Описание возможности определения офлайн-статуса

Свойство navigator.onLine возвращает логическое значение, указывающее, находится ли браузер в онлайн-режиме. Значение true означает, что браузер считает себя онлайн, а false — офлайн. Стоит учитывать, что браузер может сообщать о статусе онлайн, даже если компьютер подключен к сети, но не имеет доступа к интернету.

События online и offline срабатывают на объекте window при изменении состояния сети. Они не принимают аргументов и не возвращают значений. Их можно использовать для подписки на изменения статуса подключения.

Возможности этого API часто используются в прогрессивных веб-приложениях (PWA) для улучшения пользовательского опыта, например, для показа уведомления о потере соединения или для переключения на кешированные данные.

Короткие примеры использования

Пример проверки текущего состояния сети:

console.log('Текущий статус онлайн:', navigator.onLine);
// Выведет: Текущий статус онлайн: true (или false)
Текущий статус онлайн: true

Пример подписки на события изменения статуса сети:

window.addEventListener('online', () => {
  console.log('Сеть восстановлена.');
});

window.addEventListener('offline', () => {
  console.log('Соединение с сетью потеряно.');
});
// При отключении интернета в браузере:
Соединение с сетью потеряно.
// При восстановлении соединения:
Сеть восстановлена.

Похожие возможности в JavaScript

Прямых альтернатив для определения офлайн-статуса в браузере не существует, так как это нативное API. Однако, для более точной проверки доступности сети можно использовать другие подходы:

  • fetch() или XMLHttpRequest для проверки доступности конкретного ресурса. Этот метод позволяет убедиться не только в наличии соединения, но и в доступности бэкенда.
  • Service Worker API и Cache API для создания офлайн-функциональности и управления кешированными ресурсами.

navigator.onLine удобно использовать для быстрой проверки состояния, а запросы к серверу — для точного подтверждения доступности сети.

Аналоги в других языках программирования

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

Пример на Python с использованием библиотеки socket:

import socket

def check_internet(host="8.8.8.8", port=53, timeout=3):
    try:
        socket.setdefaulttimeout(timeout)
        socket.socket(socket.AF_INET, socket.SOCK_STREAM).connect((host, port))
        return True
    except socket.error:
        return False

print("Интернет доступен:", check_internet())
Интернет доступен: True

Пример на PHP с использованием проверки DNS:

function is_online($host = 'www.google.com') {
    return checkdnsrr($host, 'A');
}

var_dump(is_online());
bool(true)

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

Типичные ошибки

1. Слишком частое использование navigator.onLine в цикле. Это свойство не требует постоянного опроса, так как есть события для отслеживания изменений.

// Плохой пример
setInterval(() => {
  if (!navigator.onLine) {
    showOfflineWarning();
  }
}, 100);

2. Неучёт того, что статус online не гарантирует доступность конкретного сервера. Браузер может быть подключен к локальной сети без выхода в интернет.

if (navigator.onLine) {
  fetch('/api/data') // Этот запрос всё ещё может завершиться ошибкой
    .catch(() => console.log('Сервер недоступен, хотя статус онлайн.'));
}

3. Попытка использовать события online/offline в Node.js, где они не существуют. Эти события доступны только в среде браузера.

Изменения в последних версиях

Спецификация API NavigatorOnLine остаётся стабильной в течение многих лет и не претерпела значительных изменений. Основные улучшения связаны с интеграцией этого API с другими веб-технологиями, такими как Service Workers и Fetch API, для создания более надежных офлайн-сценариев в прогрессивных веб-приложениях.

Современные браузеры одинаково поддерживают свойство navigator.onLine и события online/offline. Разработчикам рекомендуется всегда проверять актуальную поддержку на ресурсах типа Can I Use, хотя проблем с совместимостью обычно нет.

Расширенные примеры использования

Создание компонента, отображающего текущий статус сети:

Пример javascript
class NetworkStatus extends HTMLElement {
  constructor() {
    super();
    this.status = navigator.onLine;
    this.render();
    window.addEventListener('online', () => this.updateStatus(true));
    window.addEventListener('offline', () => this.updateStatus(false));
  }

  updateStatus(isOnline) {
    this.status = isOnline;
    this.render();
  }

  render() {
    this.innerHTML = `
      <div style="padding: 1em; background: ${this.status ? '#d4edda' : '#f8d7da' }">
        Статус сети: <strong>${this.status ? 'ОНЛАЙН' : 'ОФЛАЙН'}</strong>
      </div>
    `;
  }
}

customElements.define('network-status', NetworkStatus);
// После добавления <network-status></network-status> в HTML будет отображаться блок с текущим статусом, который меняется автоматически.

Интеграция с менеджером запросов для автоматической паузы при потере соединения:

Пример javascript
let isNetworkOnline = navigator.onLine;
const requestQueue = [];

window.addEventListener('offline', () => {
  isNetworkOnline = false;
  console.log('Запросы поставлены в очередь.');
});

window.addEventListener('online', () => {
  isNetworkOnline = true;
  console.log('Сеть восстановлена, отправка очереди запросов.');
  requestQueue.forEach(req => req());
  requestQueue.length = 0;
});

function safeFetch(url, options) {
  if (!isNetworkOnline) {
    console.log('Запрос отложен:', url);
    return new Promise((resolve) => {
      requestQueue.push(() => resolve(fetch(url, options)));
    });
  }
  return fetch(url, options);
}

// Использование
safeFetch('/api/data').then(response => console.log('Данные получены'));
// При отключении сети:
Запрос отложен: /api/data
// При восстановлении сети:
Сеть восстановлена, отправка очереди запросов.
Данные получены

JS offline function comments

En
Offline Event fired when the browser has lost network access