У меня есть веб-приложение 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
Есть ли способ, которым это может быть достигнуто?
если эти пакеты используют событие «офлайн» / «онлайн», вы можете обмануть его, создав это событие window.dispatchEvent(new Event('offline'))
.
Так вы на самом деле хотите получить этот ложноположительный результат?
@ Берги Да. Я процитировал часть MDN о ложных срабатываниях, чтобы привести еще один мотивирующий пример, почему можно было бы реализовать свою собственную логику для onLine
. В общем, проблема в том, что приложения заботятся о том, «доступен ли мой сервер», но navigator.onLine
на самом деле не отвечает на этот вопрос, но библиотеки используют его для этого.
Я не вижу, как установка onLine
константы true
решает эту проблему — это просто означает, что значение будет ложным (неправильным) чаще, чем раньше. Скорее сообщайте о проблемах сопровождающим библиотеки, чтобы исправить ошибки.
@Bergi В целом я согласен, onLine
- это грубая эвристика, и библиотеки общего назначения должны избегать жесткого кодирования грубой эвристики. Но большинство библиотек, похоже, в первую очередь думают об «Интернете», а не о новых вариантах использования, которые также работают в автономном режиме / на локальном хосте; для приложений только для Интернета эвристика имеет смысл (например, имеет смысл не повторять попытки, если приложение только для Интернета находится в автономном режиме). Так что будет много убедительных аргументов. Для меня настоящая ошибка заключается в том, что API браузера не предлагает способа контролировать, каким должен быть onLine
. Вариант использования знает только разработчик приложения верхнего уровня.
вы можете исправить его с помощью 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
).
Натяжной целью может быть реализация комментария bogdanoff
к моему вопросу и сделать так, чтобы, если кто-то подпишется на прослушиватель автономных событий, ему даже не позвонили. Если бы это можно было добавить к ответу, было бы еще лучше. Но я уже приму ответ, так как мой первоначальный вопрос касался только свойства onLine
.
@nh2 вы можете легко и по прототипу
@mplungjan См. «чтобы не исправлять все библиотеки зависимостей, которые использует мое приложение» в описании вопроса.