Làm cách nào để phát hiện kết nối Internet đang ngoại tuyến trong JavaScript?
Làm cách nào để phát hiện kết nối Internet đang ngoại tuyến trong JavaScript?
Câu trả lời:
Bạn có thể xác định rằng kết nối bị mất bằng cách thực hiện các yêu cầu XHR không thành công .
Cách tiếp cận tiêu chuẩn là thử lại yêu cầu một vài lần. Nếu không được, hãy thông báo cho người dùng để kiểm tra kết nối và không thành công .
Sidenote: Để đặt toàn bộ ứng dụng ở trạng thái "ngoại tuyến" có thể dẫn đến nhiều công việc xử lý dễ bị lỗi .. các kết nối không dây có thể đến và đi, v.v. Vì vậy, cách tốt nhất của bạn có thể là thất bại một cách duyên dáng, bảo toàn dữ liệu và cảnh báo người dùng .. cho phép họ cuối cùng khắc phục sự cố kết nối nếu có và tiếp tục sử dụng ứng dụng của bạn với một lượng tha thứ hợp lý.
Sidenote: Bạn có thể kiểm tra một trang web đáng tin cậy như google để kết nối, nhưng điều này có thể không hoàn toàn hữu ích vì chỉ cố gắng thực hiện yêu cầu của riêng bạn, bởi vì trong khi Google có thể có sẵn, ứng dụng của riêng bạn có thể không, và bạn vẫn sẽ phải xử lý vấn đề kết nối của riêng bạn. Cố gắng gửi ping đến google sẽ là một cách tốt để xác nhận rằng chính kết nối internet bị hỏng, vì vậy nếu thông tin đó hữu ích cho bạn, thì nó có thể gây rắc rối.
Sidenote : Gửi Ping có thể đạt được giống như cách bạn thực hiện bất kỳ loại yêu cầu ajax hai chiều nào, nhưng gửi ping đến google, trong trường hợp này, sẽ đặt ra một số thách thức. Đầu tiên, chúng ta sẽ có các vấn đề liên tên miền tương tự thường gặp khi thực hiện liên lạc Ajax. Một tùy chọn là thiết lập proxy phía máy chủ, trong đó chúng tôi thực sự ping
google (hoặc bất kỳ trang web nào) và trả lại kết quả ping cho ứng dụng. Đây là một cái bẫy-22bởi vì nếu kết nối internet thực sự là vấn đề, chúng tôi sẽ không thể truy cập máy chủ và nếu sự cố kết nối chỉ nằm trên miền của chúng tôi, chúng tôi sẽ không thể phân biệt được. Các kỹ thuật tên miền chéo khác có thể được thử, ví dụ: nhúng iframe trong trang của bạn trỏ đến google.com, sau đó bỏ phiếu iframe để thành công / thất bại (kiểm tra nội dung, v.v.). Nhúng một hình ảnh có thể không thực sự cho chúng ta biết bất cứ điều gì, bởi vì chúng ta cần một phản hồi hữu ích từ cơ chế giao tiếp để đưa ra kết luận tốt về những gì đang diễn ra. Vì vậy, một lần nữa, việc xác định trạng thái của kết nối internet nói chung có thể gặp nhiều rắc rối hơn giá trị của nó. Bạn sẽ phải cân nhắc các tùy chọn này cho ứng dụng cụ thể của mình.
IE 8 sẽ hỗ trợ window.navigator.onLine .
Nhưng tất nhiên điều đó không giúp ích gì với các trình duyệt hoặc hệ điều hành khác. Tôi dự đoán các nhà cung cấp trình duyệt khác sẽ quyết định cung cấp thuộc tính đó cũng như tầm quan trọng của việc biết trạng thái trực tuyến / ngoại tuyến trong các ứng dụng Ajax.
Cho đến khi điều đó xảy ra, XHR hoặc một Image()
hoặc <img>
yêu cầu có thể cung cấp một cái gì đó gần với chức năng bạn muốn.
Cập nhật (2014/11/16)
Các trình duyệt chính hiện hỗ trợ thuộc tính này, nhưng kết quả của bạn sẽ thay đổi.
Trích dẫn từ Tài liệu Mozilla :
Trong Chrome và Safari, nếu trình duyệt không thể kết nối với mạng cục bộ (LAN) hoặc bộ định tuyến thì nó sẽ ngoại tuyến; tất cả các điều kiện khác trở lại
true
. Vì vậy, trong khi bạn có thể cho rằng trình duyệt ngoại tuyến khi nó trả về mộtfalse
giá trị, bạn không thể cho rằng một giá trị thực sự nhất thiết có nghĩa là trình duyệt có thể truy cập internet. Bạn có thể nhận được thông báo sai, chẳng hạn như trong trường hợp máy tính đang chạy phần mềm ảo hóa có bộ điều hợp ethernet ảo luôn được "kết nối". Do đó, nếu bạn thực sự muốn xác định trạng thái trực tuyến của trình duyệt, bạn nên phát triển các phương tiện bổ sung để kiểm tra.Trong Firefox và Internet Explorer, chuyển đổi trình duyệt sang chế độ ngoại tuyến sẽ gửi một
false
giá trị. Tất cả các điều kiện khác trả về mộttrue
giá trị.
Hầu như tất cả các trình duyệt chính hiện nay đều hỗ trợ thuộc window.navigator.onLine
tính và các sự kiện tương ứng online
và offline
cửa sổ:
window.addEventListener('online', () => console.log('came online'));
window.addEventListener('offline', () => console.log('came offline'));
Hãy thử đặt hệ thống hoặc trình duyệt của bạn ở chế độ ngoại tuyến / trực tuyến và kiểm tra bảng điều khiển hoặc thuộc window.navigator.onLine
tính để biết các thay đổi giá trị. Bạn có thể kiểm tra nó trên trang web này là tốt.
Lưu ý tuy nhiên trích dẫn này từ Tài liệu Mozilla :
Trong Chrome và Safari, nếu trình duyệt không thể kết nối với mạng cục bộ (LAN) hoặc bộ định tuyến thì nó sẽ ngoại tuyến; tất cả các điều kiện khác trở lại
true
. Vì vậy, trong khi bạn có thể cho rằng trình duyệt ngoại tuyến khi trả về mộtfalse
giá trị , bạn không thể cho rằng mộttrue
giá trị nhất thiết có nghĩa là trình duyệt có thể truy cập internet . Bạn có thể nhận được thông báo sai, chẳng hạn như trong trường hợp máy tính đang chạy phần mềm ảo hóa có bộ điều hợp ethernet ảo luôn được "kết nối". Do đó, nếu bạn thực sự muốn xác định trạng thái trực tuyến của trình duyệt, bạn nên phát triển các phương tiện bổ sung để kiểm tra.Trong Firefox và Internet Explorer, chuyển đổi trình duyệt sang chế độ ngoại tuyến sẽ gửi một
false
giá trị. Cho đến Firefox 41, tất cả các điều kiện khác trả về mộttrue
giá trị; kể từ Firefox 41, trên OS X và Windows, giá trị sẽ tuân theo kết nối mạng thực tế.
(nhấn mạnh là của riêng tôi)
Điều này có nghĩa là nếu window.navigator.onLine
là false
(hoặc bạn nhận được một offline
sự kiện), bạn được đảm bảo không có kết nối Internet.
true
Tuy nhiên, nếu đó là (hoặc bạn nhận được một online
sự kiện), điều đó chỉ có nghĩa là hệ thống được kết nối với một số mạng, tốt nhất. Điều đó không có nghĩa là bạn có quyền truy cập Internet chẳng hạn. Để kiểm tra điều đó, bạn vẫn sẽ cần sử dụng một trong những giải pháp được mô tả trong các câu trả lời khác.
Ban đầu tôi dự định đăng bài này như một bản cập nhật cho câu trả lời của Grant Wagner , nhưng dường như quá nhiều chỉnh sửa, đặc biệt là xem xét rằng bản cập nhật 2014 không phải từ anh ấy .
Có một số cách để làm điều này:
Bạn có thể đặt onerror
một img
, như
<img src='http://www.example.com/singlepixel.gif'
onerror='alert("Connection dead");' />
Phương pháp này cũng có thể thất bại nếu hình ảnh nguồn được di chuyển / đổi tên và thường sẽ là một lựa chọn kém hơn so với tùy chọn ajax.
Vì vậy, có một số cách khác nhau để thử và phát hiện điều này, không có cách nào hoàn hảo, nhưng trong trường hợp không có khả năng nhảy ra khỏi hộp cát trình duyệt và truy cập trực tiếp trạng thái kết nối mạng của người dùng, chúng dường như là những lựa chọn tốt nhất.
if(navigator.onLine){
alert('online');
} else {
alert('offline');
}
Bạn có thể sử dụng hàm gọi lại của $ .ajax ()error
, sẽ kích hoạt nếu yêu cầu không thành công. Nếu textStatus
bằng chuỗi "hết thời gian" thì có lẽ kết nối bị ngắt:
function (XMLHttpRequest, textStatus, errorThrown) {
// typically only one of textStatus or errorThrown
// will have info
this; // the options for this ajax request
}
Từ tài liệu :
Lỗi : Một chức năng được gọi nếu yêu cầu không thành công. Hàm được truyền ba đối số: Đối tượng XMLHttpRequest, một chuỗi mô tả loại lỗi xảy ra và một đối tượng ngoại lệ tùy chọn, nếu xảy ra. Các giá trị có thể có cho đối số thứ hai (ngoài null) là "hết thời gian", "lỗi", "không sửa đổi" và "trình phân tích cú pháp". Đây là một sự kiện Ajax
Ví dụ:
$.ajax({
type: "GET",
url: "keepalive.php",
success: function(msg){
alert("Connection active!")
},
error: function(XMLHttpRequest, textStatus, errorThrown) {
if(textStatus == 'timeout') {
alert('Connection seems dead!');
}
}
});
Như olliej đã nói, sử dụng thuộc tính navigator.onLine
trình duyệt tốt hơn là gửi các yêu cầu mạng và, theo đó là developer.mozilla.org/En/Online_and_offline_events , nó thậm chí còn được hỗ trợ bởi các phiên bản Firefox và IE cũ.
Gần đây, WHATWG đã chỉ định bổ sung online
và offline
các sự kiện, trong trường hợp bạn cần phản ứng với các navigator.onLine
thay đổi.
Cũng xin chú ý đến liên kết được đăng bởi Daniel Silveira, điều này chỉ ra rằng việc dựa vào các tín hiệu / thuộc tính đó để đồng bộ hóa với máy chủ không phải lúc nào cũng là một ý tưởng hay.
window.navigator.onLine
là những gì bạn đang tìm kiếm, nhưng một vài thứ ở đây cần thêm vào, trước tiên, nếu đó là thứ gì đó trên ứng dụng của bạn mà bạn muốn tiếp tục kiểm tra (như để xem liệu người dùng có đột nhiên ngoại tuyến hay không, điều này đúng trong trường hợp này, thì bạn sẽ cũng cần lắng nghe để thay đổi), để bạn thêm trình lắng nghe sự kiện vào cửa sổ để phát hiện bất kỳ thay đổi nào, để kiểm tra xem người dùng có ngoại tuyến không, bạn có thể thực hiện:
window.addEventListener("offline",
()=> console.log("No Internet")
);
và để kiểm tra nếu trực tuyến:
window.addEventListener("online",
()=> console.log("Connected Internet")
);
onLine
. Trình duyệt xác định trạng thái trực tuyến rất khác nhau. Hãy xem developer.mozilla.org/en-US/docs/Web/API/NavigatorOnLine/onLine .
Tôi đã phải tạo một ứng dụng web (dựa trên ajax) cho một khách hàng làm việc nhiều với các trường học, những trường này thường có kết nối internet xấu Tôi sử dụng chức năng đơn giản này để phát hiện nếu có kết nối, hoạt động rất tốt!
Tôi sử dụng CodeIgniter và 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();
}
});
}
một cuộc gọi ajax đến miền của bạn là cách dễ nhất để phát hiện nếu bạn ngoại tuyến
$.ajax({
type: "HEAD",
url: document.location.pathname + "?param=" + new Date(),
error: function() { return false; },
success: function() { return true; }
});
Đây chỉ là để cung cấp cho bạn khái niệm, nó cần được cải thiện.
Ví dụ: error = 404 vẫn có nghĩa là bạn trực tuyến
Tôi nghĩ đó là một cách rất đơn giản.
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
Tôi đang tìm kiếm một giải pháp phía khách hàng để phát hiện xem internet có bị sập hay máy chủ của tôi bị sập không. Các giải pháp khác mà tôi thấy dường như luôn phụ thuộc vào tệp hoặc hình ảnh tập lệnh của bên thứ 3, mà theo tôi dường như nó sẽ không vượt qua được thử thách của thời gian. Một tập lệnh hoặc hình ảnh được lưu trữ bên ngoài có thể thay đổi trong tương lai và khiến mã phát hiện bị lỗi.
Tôi đã tìm thấy một cách để phát hiện nó bằng cách tìm kiếm một xhrStatus với mã 404. Ngoài ra, tôi sử dụng JSONP để bỏ qua hạn chế CORS. Mã trạng thái khác 404 cho thấy kết nối internet không hoạt động.
$.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)
}
}
});
Cách của tôi
<!-- 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>
Vấn đề của một số phương pháp như navigator.onLine
là chúng không tương thích với một số trình duyệt và phiên bản di động, một tùy chọn giúp tôi rất nhiều là sử dụng XMLHttpRequest
phương pháp cổ điển và cũng thấy trước trường hợp có thể tệp được lưu trữ trong bộ đệm có phản hồiXMLHttpRequest.status
lớn hơn 200 và nhỏ hơn 304.
Đây là mã của tôi:
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 :(');
}
}
}
Có 2 câu trả lời cho hai kịch bản khác nhau: -
Nếu bạn đang sử dụng JavaScript trên một trang web (nghĩa là hoặc bất kỳ phần giao diện người dùng nào) Cách đơn giản nhất để làm điều đó là:
<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>
Nhưng nếu bạn đang sử dụng js ở phía máy chủ (ví dụ: nút, v.v.), bạn có thể xác định rằng kết nối bị mất bằng cách thực hiện các yêu cầu XHR không thành công.
Cách tiếp cận tiêu chuẩn là thử lại yêu cầu một vài lần. Nếu không được, hãy thông báo cho người dùng để kiểm tra kết nối và không thành công.
yêu cầu đầu trong lỗi yêu cầu
$.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");
}
});
}
});
Đây là một đoạn của một tiện ích trợ giúp tôi có. Đây là javascript được đặt tên:
network: function() {
var state = navigator.onLine ? "online" : "offline";
return state;
}
Bạn nên sử dụng phương pháp này với phương pháp phát hiện khác để loại bỏ cách 'thay thế' này. Thời gian đang đến rất nhanh khi đây sẽ là tất cả những gì cần thiết. Các phương pháp khác là hack.