Как обнаружить интернет-соединение в автономном режиме в JavaScript?
Как обнаружить интернет-соединение в автономном режиме в JavaScript?
Ответы:
Вы можете определить, что соединение потеряно, выполнив неудачные запросы XHR .
Стандартный подход - повторить запрос несколько раз. Если этого не произойдет, предупредите пользователя, чтобы он проверил соединение, и завершите с ошибкой .
Sidenote: перевод всего приложения в автономное состояние может привести к большой подверженности ошибкам работе по обработке состояния. Беспроводные соединения могут приходить и уходить и т. Д. Поэтому лучше всего просто изящно завершить работу, сохранить данные, и предупредить пользователя .. позволяя им в конечном итоге решить проблему с подключением, если таковая имеется, и продолжать использовать ваше приложение с достаточным количеством прощения.
Примечание. Вы можете проверить наличие надежного сайта, такого как Google, на предмет подключения, но это может быть не совсем полезным, поскольку вы просто пытаетесь сделать свой собственный запрос, потому что, хотя Google может быть доступен, ваше собственное приложение может и не быть, и вы все равно будете приходится решать ваши собственные проблемы с подключением. Попытка отправить пинг в Google была бы хорошим способом подтвердить, что интернет-соединение отключено, поэтому, если эта информация вам полезна, то это может стоить хлопот.
Замечание . Отправка Ping может быть осуществлена так же, как если бы вы делали двусторонний Ajax-запрос любого типа, но отправка Ping в Google в этом случае создаст некоторые проблемы. Во-первых, у нас будут те же междоменные проблемы, которые обычно возникают при создании Ajax-коммуникаций. Один из вариантов - настроить прокси на стороне сервера, в котором мы на самом деле ping
Google (или любой другой сайт), и вернуть результаты пинга в приложение. Это уловка-22потому что если проблема связана с интернет-соединением, мы не сможем добраться до сервера, и если проблема с подключением будет только в нашем собственном домене, мы не сможем заметить разницу. Можно попробовать другие междоменные методы, например, встроить на свою страницу iframe, который указывает на google.com, а затем опросить iframe на предмет успеха / неудачи (проверить содержимое и т. Д.). Встраивание изображения может ничего не сказать нам, потому что нам нужен полезный ответ от коммуникационного механизма, чтобы сделать хороший вывод о том, что происходит. Итак, еще раз, определение состояния интернет-соединения в целом может быть больше проблем, чем оно того стоит. Вам придется взвесить эти опции для вашего конкретного приложения.
IE 8 будет поддерживать свойство window.navigator.onLine .
Но, конечно, это не помогает с другими браузерами или операционными системами. Я предполагаю, что другие поставщики браузеров также примут решение предоставить это свойство, учитывая важность знания статуса онлайн / офлайн в приложениях Ajax.
Пока этого не произойдет, либо XHR, либо запрос Image()
или <img>
могут предоставить что-то близкое к желаемой функциональности.
Обновление (2014/11/16)
Основные браузеры теперь поддерживают это свойство, но ваши результаты будут отличаться.
Цитата из документации Mozilla :
В Chrome и Safari, если браузер не может подключиться к локальной сети (LAN) или маршрутизатору, он находится в автономном режиме; все остальные условия возвращаются
true
. Таким образом, хотя вы можете предполагать, что браузер находится в автономном режиме, когда он возвращаетfalse
значение, вы не можете предполагать, что истинное значение обязательно означает, что браузер может получить доступ к Интернету. Вы можете получить ложные срабатывания, например, в тех случаях, когда на компьютере запущено программное обеспечение для виртуализации с виртуальными адаптерами Ethernet, которые всегда «подключены». Поэтому, если вы действительно хотите определить онлайн-статус браузера, вам следует разработать дополнительные средства для проверки.В Firefox и Internet Explorer переключение браузера в автономный режим отправляет
false
значение. Все остальные условия возвращаютtrue
значение.
Почти все основные браузеры теперь поддерживают window.navigator.onLine
свойство, а также соответствующие события online
и offline
окна:
window.addEventListener('online', () => console.log('came online'));
window.addEventListener('offline', () => console.log('came offline'));
Попробуйте настроить систему или браузер в автономном / онлайн-режиме и проверьте консоль или window.navigator.onLine
свойство на предмет изменения значений. Вы также можете проверить это на этом сайте .
Обратите внимание на эту цитату из документации Mozilla :
В Chrome и Safari, если браузер не может подключиться к локальной сети (LAN) или маршрутизатору, он находится в автономном режиме; все остальные условия возвращаются
true
. Таким образом, хотя вы можете предполагать, что браузер находится в автономном режиме, когда он возвращаетfalse
значение , вы не можете предполагать, чтоtrue
значение обязательно означает, что браузер может получить доступ к Интернету . Вы можете получить ложные срабатывания, например, в тех случаях, когда на компьютере запущено программное обеспечение для виртуализации с виртуальными адаптерами Ethernet, которые всегда «подключены». Поэтому, если вы действительно хотите определить онлайн-статус браузера, вам следует разработать дополнительные средства для проверки.В Firefox и Internet Explorer переключение браузера в автономный режим отправляет
false
значение. До Firefox 41 все остальные условия возвращаютtrue
значение; начиная с Firefox 41 в OS X и Windows, значение будет соответствовать фактическому сетевому подключению.
(акцент мой)
Это означает, что если window.navigator.onLine
есть false
(или вы получаете offline
событие), вы гарантированно не будете иметь подключения к Интернету.
Однако, если это так true
(или вы получаете online
событие), это означает, что система в лучшем случае только подключена к какой-либо сети. Это не значит, что у вас есть доступ к интернету например. Чтобы проверить это, вам все равно нужно будет использовать одно из решений, описанных в других ответах.
Первоначально я намеревался опубликовать это как обновление к ответу Гранта Вагнера , но это казалось слишком большой правкой, особенно учитывая, что обновление 2014 года уже не от него .
Есть несколько способов сделать это:
Вы можете положить onerror
в img
, как
<img src='http://www.example.com/singlepixel.gif'
onerror='alert("Connection dead");' />
Этот метод может также потерпеть неудачу, если исходное изображение будет перемещено / переименовано, и, как правило, будет худшим выбором для опции ajax.
Таким образом, есть несколько разных способов попытаться обнаружить это, но ни один из них не идеален, но в отсутствие возможности выпрыгнуть из изолированной программной среды браузера и напрямую получить доступ к состоянию сетевого подключения пользователя, они кажутся лучшими вариантами.
if(navigator.onLine){
alert('online');
} else {
alert('offline');
}
Вы можете использовать $ .ajax () «s error
обратного вызова, который срабатывает , если запрос не удается. Если textStatus
равно строке "timeout", это, вероятно, означает, что соединение разорвано:
function (XMLHttpRequest, textStatus, errorThrown) {
// typically only one of textStatus or errorThrown
// will have info
this; // the options for this ajax request
}
Из документа :
Ошибка : функция, вызываемая в случае сбоя запроса. Функции передается три аргумента: объект XMLHttpRequest, строка, описывающая тип возникшей ошибки и необязательный объект исключения, если таковой произошел. Возможные значения для второго аргумента (кроме нуля): «timeout», «error», «notmodified» и «parsererror». Это событие Ajax
Так, например:
$.ajax({
type: "GET",
url: "keepalive.php",
success: function(msg){
alert("Connection active!")
},
error: function(XMLHttpRequest, textStatus, errorThrown) {
if(textStatus == 'timeout') {
alert('Connection seems dead!');
}
}
});
Как сказал olliej, использование navigator.onLine
свойства браузера предпочтительнее, чем отправка сетевых запросов, и, соответственно с developer.mozilla.org/En/Online_and_offline_events , оно даже поддерживается старыми версиями Firefox и IE.
В последнее время WHATWG уточнил сложение online
и offline
событий, в случае , если вам нужно реагировать на navigator.onLine
изменения.
Обратите также внимание на ссылку, размещенную Даниэлем Сильвейрой, в которой указано, что полагаться на эти сигналы / свойства для синхронизации с сервером не всегда хорошая идея.
window.navigator.onLine
это то, что вы ищете, но здесь есть несколько вещей, которые нужно добавить, во-первых, если в вашем приложении есть что-то, что вы хотите постоянно проверять (например, посмотреть, вдруг ли пользователь внезапно переходит в автономный режим, что в большинстве случаев правильно, то вы необходимо также прослушать изменения), для этого вы добавляете прослушиватель событий в окно, чтобы обнаружить любые изменения, для проверки, переходит ли пользователь в автономный режим, вы можете сделать:
window.addEventListener("offline",
()=> console.log("No Internet")
);
и для проверки, если онлайн:
window.addEventListener("online",
()=> console.log("Connected Internet")
);
onLine
. Браузеры определяют состояние онлайн совсем по-другому. Взгляните на developer.mozilla.org/en-US/docs/Web/API/NavigatorOnLine/onLine .
Я должен был сделать веб-приложение (на основе ajax) для клиента, который много работает со школами, у этих школ часто плохое интернет-соединение. Я использую эту простую функцию, чтобы определить, есть ли соединение, работает очень хорошо!
Я использую CodeIgniter и Jquery:
function checkOnline() {
setTimeout("doOnlineCheck()", 20000);
}
function doOnlineCheck() {
//if the server can be reached it returns 1, other wise it times out
var submitURL = $("#base_path").val() + "index.php/menu/online";
$.ajax({
url : submitURL,
type : "post",
dataType : "msg",
timeout : 5000,
success : function(msg) {
if(msg==1) {
$("#online").addClass("online");
$("#online").removeClass("offline");
} else {
$("#online").addClass("offline");
$("#online").removeClass("online");
}
checkOnline();
},
error : function() {
$("#online").addClass("offline");
$("#online").removeClass("online");
checkOnline();
}
});
}
Ajax-вызов вашего домена - это самый простой способ определить, не подключены ли вы к сети.
$.ajax({
type: "HEAD",
url: document.location.pathname + "?param=" + new Date(),
error: function() { return false; },
success: function() { return true; }
});
это просто чтобы дать вам концепцию, она должна быть улучшена.
Например, ошибка = 404 должна означать, что вы онлайн
Я думаю, что это очень простой способ.
var x = confirm("Are you sure you want to submit?");
if (x) {
if (navigator.onLine == true) {
return true;
}
alert('Internet connection is lost');
return false;
}
return false;
if the browser is not able to connect to a local area network (LAN) or a router, it is offline; all other conditions return true
Я искал решение на стороне клиента, чтобы определить, не работает ли интернет или не работает ли мой сервер. Другие решения, которые я обнаружил, всегда зависели от файла или изображения скрипта стороннего производителя, который, на мой взгляд, не выдержал испытания временем. Внешний размещенный скрипт или изображение может измениться в будущем и привести к сбою кода обнаружения.
Я нашел способ обнаружить это, ища xhrStatus с кодом 404. Кроме того, я использую JSONP, чтобы обойти ограничение CORS. Код состояния, отличный от 404, показывает, что интернет-соединение не работает.
$.ajax({
url: 'https://www.bing.com/aJyfYidjSlA' + new Date().getTime() + '.html',
dataType: 'jsonp',
timeout: 5000,
error: function(xhr) {
if (xhr.status == 404) {
//internet connection working
}
else {
//internet is down (xhr.status == 0)
}
}
});
Мой путь.
<!-- the file named "tt.jpg" should exist in the same directory -->
<script>
function testConnection(callBack)
{
document.getElementsByTagName('body')[0].innerHTML +=
'<img id="testImage" style="display: none;" ' +
'src="tt.jpg?' + Math.random() + '" ' +
'onerror="testConnectionCallback(false);" ' +
'onload="testConnectionCallback(true);">';
testConnectionCallback = function(result){
callBack(result);
var element = document.getElementById('testImage');
element.parentNode.removeChild(element);
}
}
</script>
<!-- usage example -->
<script>
function myCallBack(result)
{
alert(result);
}
</script>
<a href=# onclick=testConnection(myCallBack);>Am I online?</a>
Проблема некоторых методов, таких как, navigator.onLine
заключается в том, что они несовместимы с некоторыми браузерами и мобильными версиями. Мне очень помог вариант, который заключался в использовании классического XMLHttpRequest
метода, а также предвидел возможный случай, когда файл был сохранен в кеше с ответом XMLHttpRequest.status
, превышающим 200 и меньше чем 304.
Вот мой код:
var xhr = new XMLHttpRequest();
//index.php is in my web
xhr.open('HEAD', 'index.php', true);
xhr.send();
xhr.addEventListener("readystatechange", processRequest, false);
function processRequest(e) {
if (xhr.readyState == 4) {
//If you use a cache storage manager (service worker), it is likely that the
//index.php file will be available even without internet, so do the following validation
if (xhr.status >= 200 && xhr.status < 304) {
console.log('On line!');
} else {
console.log('Offline :(');
}
}
}
Есть два ответа для двух разных senarios: -
Если вы используете JavaScript на веб-сайте (т. Е. Или любой другой части интерфейса), то самый простой способ сделать это:
<h2>The Navigator Object</h2>
<p>The onLine property returns true if the browser is online:</p>
<p id="demo"></p>
<script>
document.getElementById("demo").innerHTML = "navigator.onLine is " + navigator.onLine;
</script>
Но если вы используете js на стороне сервера (т. Е. Узел и т. Д.), Вы можете определить, что соединение потеряно, выполнив неудачные запросы XHR.
Стандартный подход - повторить запрос несколько раз. Если этого не произойдет, предупредите пользователя, чтобы он проверил соединение, и завершите с ошибкой.
заголовок запроса в ошибке запроса
$.ajax({
url: /your_url,
type: "POST or GET",
data: your_data,
success: function(result){
//do stuff
},
error: function(xhr, status, error) {
//detect if user is online and avoid the use of async
$.ajax({
type: "HEAD",
url: document.location.pathname,
error: function() {
//user is offline, do stuff
console.log("you are offline");
}
});
}
});
Вот фрагмент вспомогательной утилиты, которую я имею. Это пространство имен javascript:
network: function() {
var state = navigator.onLine ? "online" : "offline";
return state;
}
Вы должны использовать это с обнаружением метода, иначе запустите «альтернативный» способ сделать это. Быстро приближается время, когда это будет все, что нужно. Другие методы - это хаки.