Skip to content

Commit dcb85e9

Browse files
feat: add the "closeOnBeforeunload" option
Since [1], the socket is now closed when receiving the "beforeunload" event in the browser. This change was meant to fix a discrepancy between Chrome and Firefox when the user reloads/closes a browser tab: Firefox would close the connection (and emit a "disconnect" event, at the Socket.IO level), but not Chrome (see [2]). But it also closes the connection when there is another "beforeunload" handler, for example when the user is prompted "are you sure you want to leave this page?". Note: calling "stopImmediatePropagation()" was a possible workaround: ```js window.addEventListener('beforeunload', (event) => { event.preventDefault(); event.stopImmediatePropagation(); event.returnValue = 'are you sure you want to leave this page?'; }); ``` This commit adds a "closeOnBeforeunload" option, which controls whether a handler is registered for the "beforeunload" event. Syntax: ```js const socket = require('engine.io-client')('ws://localhost', { closeOnBeforeunload: false // defaults to true }); ``` [1]: ed48b5d [2]: socketio/socket.io#3639 Related: - #661 - #658 - socketio/socket.io-client#1451 Reference: https://developer.mozilla.org/en-US/docs/Web/API/Window/beforeunload_event
1 parent 9eeed5e commit dcb85e9

File tree

2 files changed

+19
-12
lines changed

2 files changed

+19
-12
lines changed

README.md

+1
Original file line numberDiff line numberDiff line change
@@ -267,6 +267,7 @@ Exposed as `eio` in the browser standalone build.
267267
- `requestTimeout` (`Number`): Timeout for xhr-polling requests in milliseconds (`0`)
268268
- **Websocket-only options**
269269
- `protocols` (`Array`): a list of subprotocols (see [MDN reference](https://developer.mozilla.org/en-US/docs/Web/API/WebSockets_API/Writing_WebSocket_servers#Subprotocols))
270+
- `closeOnBeforeunload` (`Boolean`): whether to silently close the connection when the [`beforeunload`](https://developer.mozilla.org/en-US/docs/Web/API/Window/beforeunload_event) event is emitted in the browser (defaults to `true`)
270271
- `send`
271272
- Sends a message to the server
272273
- **Parameters**

lib/socket.js

+18-12
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,8 @@ class Socket extends Emitter {
7070
perMessageDeflate: {
7171
threshold: 1024
7272
},
73-
transportOptions: {}
73+
transportOptions: {},
74+
closeOnBeforeunload: true
7475
},
7576
opts
7677
);
@@ -91,17 +92,22 @@ class Socket extends Emitter {
9192
this.pingTimeoutTimer = null;
9293

9394
if (typeof addEventListener === "function") {
94-
addEventListener(
95-
"beforeunload",
96-
() => {
97-
if (this.transport) {
98-
// silently close the transport
99-
this.transport.removeAllListeners();
100-
this.transport.close();
101-
}
102-
},
103-
false
104-
);
95+
if (this.opts.closeOnBeforeunload) {
96+
// Firefox closes the connection when the "beforeunload" event is emitted but not Chrome. This event listener
97+
// ensures every browser behaves the same (no "disconnect" event at the Socket.IO level when the page is
98+
// closed/reloaded)
99+
addEventListener(
100+
"beforeunload",
101+
() => {
102+
if (this.transport) {
103+
// silently close the transport
104+
this.transport.removeAllListeners();
105+
this.transport.close();
106+
}
107+
},
108+
false
109+
);
110+
}
105111
if (this.hostname !== "localhost") {
106112
this.offlineEventListener = () => {
107113
this.onClose("transport close");

0 commit comments

Comments
 (0)