I'm writing a simple Chrome extension, the behavior is needed to detect if device is connect to the Internet. I'm currently trying to connect to ping service for checking network status and it is not efficient. Is there any event to which I can listen from Chrome JavaScript API?
3 Answers
There is no specific event in the Chrome extension APIs intended to be used for this purpose.
In "How to detect online/offline event cross-browser?" it is suggested that you can use window.navigator.onLine
and the events (from MDN):
window.addEventListener('offline', function(e) { console.log('offline'); });
window.addEventListener('online', function(e) { console.log('online'); });
However, my testing on Windows 10 x64 using Chrome Version 56.0.2924.87 (64-bit) indicated that none of those are valid. When the network cable was physically disconnected, the events did not fire in either the background script, nor a content script In addition, the value of window.navigator.onLine
remained true
in both. There was a similar lack of activity when the network cable was plugged back in.
Potential events to which you might listen
However, when the network cable was disconnected a webRequest
was fired. Specifically the following events:
webRequest.onBeforeRequest -> arg[0]= Object { frameId: -1, method: "GET", parentFrameId: -1, requestId: "10787", tabId: -1, timeStamp: 1487550094371.293, type: "other", url: "https://www.google.com/searchdomaincheck?format=domain&type=chrome", __proto__: Object }
webRequest.onBeforeSendHeaders-> arg[0]= Object { frameId: -1, method: "GET", parentFrameId: -1, requestHeaders: Array[4], requestId: "10787", tabId: -1, timeStamp: 1487550094371.3901, type: "other", url: "https://www.google.com/searchdomaincheck?format=domain&type=chrome", __proto__: Object }
webRequest.onSendHeaders -> arg[0]= Object { frameId: -1, method: "GET", parentFrameId: -1, requestHeaders: Array[4], requestId: "10787", tabId: -1, timeStamp: 1487550094371.437, type: "other", url: "https://www.google.com/searchdomaincheck?format=domain&type=chrome", __proto__: Object }
webRequest.onErrorOccurred -> arg[0]= Object { error: "net::ERR_NAME_NOT_RESOLVED", frameId: -1, fromCache: false, method: "GET", parentFrameId: -1, requestId: "10787", tabId: -1, timeStamp: 1487550096326.291, type: "other", url: "https://www.google.com/searchdomaincheck?format=domain&type=chrome", __proto__: Object }
When the cable was reconnected, the following sequence of webRequests
were fired:
webRequest.onBeforeRequest -> arg[0]= Object { frameId: -1, method: "GET", parentFrameId: -1, requestId: "10938", tabId: -1, timeStamp: 1487550516485.3562, type: "other", url: "https://www.google.com/searchdomaincheck?format=domain&type=chrome", __proto__: Object }
webRequest.onBeforeSendHeaders-> arg[0]= Object { frameId: -1, method: "GET", parentFrameId: -1, requestHeaders: Array[4], requestId: "10938", tabId: -1, timeStamp: 1487550516485.523, type: "other", url: "https://www.google.com/searchdomaincheck?format=domain&type=chrome", __proto__: Object }
webRequest.onSendHeaders -> arg[0]= Object { frameId: -1, method: "GET", parentFrameId: -1, requestHeaders: Array[4], requestId: "10938", tabId: -1, timeStamp: 1487550516485.565, type: "other", url: "https://www.google.com/searchdomaincheck?format=domain&type=chrome", __proto__: Object }
webRequest.onHeadersReceived -> arg[0]= Object { frameId: -1, method: "GET", parentFrameId: -1, requestId: "10938", responseHeaders: Array[12], statusCode: 200, statusLine: "HTTP/1.1 200"tabId: -1, timeStamp: 1487550518279.5378, type: "other", url: "https://www.google.com/searchdomaincheck?format=domain&type=chrome", __proto__: Object }
webRequest.onResponseStarted -> arg[0]= Object { frameId: -1, fromCache: false, ip: "216.58.193.68", method: "GET", parentFrameId: -1, requestId: "10938", responseHeaders: Array[12], statusCode: 200, statusLine: "HTTP/1.1 200", tabId: -1, timeStamp: 1487550518279.653type: "other"url: "https://www.google.com/searchdomaincheck?format=domain&type=chrome", __proto__: Object }
webRequest.onCompleted -> arg[0]= Object { frameId: -1, fromCache: false, ip: "216.58.193.68", method: "GET", parentFrameId: -1, requestId: "10938", responseHeaders: Array[12], statusCode: 200, statusLine: "HTTP/1.1 200", tabId: -1, timeStamp: 1487550518279.754type: "other"url: "https://www.google.com/searchdomaincheck?format=domain&type=chrome", __proto__: Object }
So, it appears that good candidates for events to watch are webRequest.onErrorOccurred
for going offline and webRequest.onCompleted
for going online, both with the URL: https://www.google.com/searchdomaincheck?format=domain&type=chrome
.
This would need further testing. It was only tested on the configuration mentioned above.
On my MacBook navigator.onLine
works as expected if I turn wifi on and off.
console.log("Is the browser online? "+ navigator.onLine);
With and without wifi enabled...

- 5,974
- 4
- 53
- 51
-
Not work with a vpn and disable/enable wifi. Works without vpn and disable/enable wifi. – bronze man Jul 23 '18 at 08:20
-
Just confirmed this still works and added screenshot – ow3n Jul 23 '18 at 11:53
Consider using change event from NetworkInformation API.
This event triggers every time connection has been lost. I assume, because estimated effective round-trip time of the current connection changes in disconnected/connected state.
However, it is an experimental technology and seems doesn't work for Firefox and Safari extensions.
Here is code example:
// inside your background service worker
navigator.connection.addEventListener('change', changeHandler)
function changeHandler() {
const isOnline = navigator.onLine
// do your stuff
}

- 3,650
- 5
- 15
- 30

- 1
- 1