2

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?

Makyen
  • 31,849
  • 12
  • 86
  • 121
vun
  • 1,251
  • 1
  • 14
  • 17

3 Answers3

7

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.

Community
  • 1
  • 1
Makyen
  • 31,849
  • 12
  • 86
  • 121
4

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...

With and without wifi enabled...

ow3n
  • 5,974
  • 4
  • 53
  • 51
0

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
}
Zach Jensz
  • 3,650
  • 5
  • 15
  • 30