Переопределение window.navigator.onLine, чтобы всегда быть в сети

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

Как описано в документах onLine,

В Chrome и Safari, если браузер не может подключиться к локальной сети (LAN) или маршрутизатору, он находится в автономном режиме.

Однако мое приложение должно работать, даже если сетевой интерфейс не подключен.


Еще один мотивирующий пример, почему можно переопределить onLine:

MDN указывает на другие ситуации, в которых window.navigator.onLine не дает нужной информации (здесь ложные срабатывания):

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


По этим причинам, а также чтобы не исправлять все библиотеки зависимостей, которые использует мое приложение, я хочу переопределить window.navigator.onLine, чтобы оно всегда возвращало true.

Тем не менее, похоже, это свойство readonly.

Я уже пробовал использовать Proxy, вот так:

if (window.navigator) {
  // `as any` to ignore `readonly` property
  (window.navigator as any) = new Proxy(window.navigator, {
    // See https://javascript.info/proxy
    get(target, prop, ...rest) {
      if (prop === "onLine") {
        return true;
      }
      return Reflect.get(target, prop, ...rest);
    },
  });
}

но при заданиях window.navigator = ... я получаю ошибку, например. Хром 111:

Cannot set property navigator of #<Window> which has only a getter

Есть ли способ, которым это может быть достигнуто?

@mplungjan См. «чтобы не исправлять все библиотеки зависимостей, которые использует мое приложение» в описании вопроса.

nh2 18.04.2023 16:12

если эти пакеты используют событие «офлайн» / «онлайн», вы можете обмануть его, создав это событие window.dispatchEvent(new Event('offline')).

bogdanoff 18.04.2023 16:19

Так вы на самом деле хотите получить этот ложноположительный результат?

Bergi 18.04.2023 16:26

@ Берги Да. Я процитировал часть MDN о ложных срабатываниях, чтобы привести еще один мотивирующий пример, почему можно было бы реализовать свою собственную логику для onLine. В общем, проблема в том, что приложения заботятся о том, «доступен ли мой сервер», но navigator.onLine на самом деле не отвечает на этот вопрос, но библиотеки используют его для этого.

nh2 18.04.2023 17:32

Я не вижу, как установка onLine константы true решает эту проблему — это просто означает, что значение будет ложным (неправильным) чаще, чем раньше. Скорее сообщайте о проблемах сопровождающим библиотеки, чтобы исправить ошибки.

Bergi 18.04.2023 17:45

@Bergi В целом я согласен, onLine - это грубая эвристика, и библиотеки общего назначения должны избегать жесткого кодирования грубой эвристики. Но большинство библиотек, похоже, в первую очередь думают об «Интернете», а не о новых вариантах использования, которые также работают в автономном режиме / на локальном хосте; для приложений только для Интернета эвристика имеет смысл (например, имеет смысл не повторять попытки, если приложение только для Интернета находится в автономном режиме). Так что будет много убедительных аргументов. Для меня настоящая ошибка заключается в том, что API браузера не предлагает способа контролировать, каким должен быть onLine. Вариант использования знает только разработчик приложения верхнего уровня.

nh2 18.04.2023 17:57
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
0
6
80
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

вы можете исправить его с помощью getter или записи. Я буду использовать геттер, чтобы обеспечить правильность даже для внедренных браузеров, таких как Avas: (это отрицательный способ, если возможно, исправить их вместо перезаписи):

Object.defineProperty(window.navigator, 'onLine', {
  get: () => true
})

console.info('navigator.onLine = %s', navigator.onLine)

для тех, кто хочет протестировать этот код, но не хочет отключаться, попробуйте следующий автономный автономный код

Object.defineProperty(window.navigator, 'onLine', {
  get: () => false
})

console.info('navigator.onLine = %s', navigator.onLine)

Отлично, кажется, это работает. Это может быть протестировано, например. с помощью Chrome Dev Tools на вкладке «Сеть» установите для раскрывающегося списка «Дросселирование» значение Offline (обычно это значение navigator.onLine = false, но с вашим кодом оно остается true).

nh2 18.04.2023 17:48

Натяжной целью может быть реализация комментария bogdanoff к моему вопросу и сделать так, чтобы, если кто-то подпишется на прослушиватель автономных событий, ему даже не позвонили. Если бы это можно было добавить к ответу, было бы еще лучше. Но я уже приму ответ, так как мой первоначальный вопрос касался только свойства onLine.

nh2 18.04.2023 17:59

@nh2 вы можете легко и по прототипу

Tachibana Shin 19.04.2023 01:14

Другие вопросы по теме