Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Replace XMLHttpRequest with fetch #4980

Closed
Juraj-Masiar opened this issue Mar 19, 2024 · 2 comments
Closed

Replace XMLHttpRequest with fetch #4980

Juraj-Masiar opened this issue Mar 19, 2024 · 2 comments
Labels
enhancement New feature or request

Comments

@Juraj-Masiar
Copy link

Is your feature request related to a problem? Please describe.
Currently, socket.io can't be used in Chrome extension background script, since modern Manifest V3 extensions are using service worker as a background script (which doesn't have XMLHttpRequest, only fetch).
Example error:

reason
'xhr poll error'
description
TypeError: xhr.open is not a function
    at Request.create (polling.js:250:1)
    at new Request (polling.js:237:1)
    at Polling.request (polling.js:190:1)
    at Polling.doPoll (polling.js:215:1)
    at Polling.poll (polling.js:96:1)
    at Polling.doOpen (polling.js:56:1)
    at Polling.open (transport.js:46:1)
    at Socket.open (socket.js:170:1)
    at new Socket (socket.js:111:1)
    at Manager.open (manager.js:108:1)

Describe the solution you'd like
Replacing XMLHttpRequest with modern fetch.

Describe alternatives you've considered
I think using transports: ['websocket'], would help, but that way I can't use extraHeaders which I use for authorization.

Additional context

"socket.io-client": "^4.7.5",
@Juraj-Masiar Juraj-Masiar added the enhancement New feature or request label Mar 19, 2024
@darrachequesne
Copy link
Member

We could indeed provide another implementation for the HTTP long-polling transport, something like:

import { io } from "socket.io-client";

const socket = io({
  transports: [
    PollingWithFetch,
    WebSocket
  ]
});

Related: socketio/engine.io-client#716

darrachequesne added a commit to socketio/engine.io-client that referenced this issue Apr 23, 2024
Usage:

```js
import { Socket, transports, Fetch } from "engine.io-client";

transports.polling = Fetch;

const socket = new Socket("https://example.com");
```

Note: tree-shaking unused transports is not currently supported and
will be added later.

Related:

- socketio/socket.io#4980
- #716
darrachequesne added a commit to socketio/engine.io-client that referenced this issue May 31, 2024
This commit adds the ability to provide a list of transport
implementations to use when connecting to an Engine.IO server.

This can be used to use HTTP long-polling based on `fetch()`, instead
of the default implementation based on the `XMLHttpRequest` object.

```
import { Socket, Fetch, WebSocket } from "engine.io-client";

const socket = new Socket({
  transports: [Fetch, WebSocket]
});
```

This is useful in some environments that do not provide a
`XMLHttpRequest` object, like Chrome extension background scripts.

> XMLHttpRequest() can't be called from a service worker, extension or
otherwise. Replace calls from your background script to
XMLHttpRequest() with calls to global fetch().

Source: https://developer.chrome.com/docs/extensions/develop/migrate/to-service-workers#replace-xmlhttprequest

Related:

- #716
- socketio/socket.io#4980

This is also useful when running the client with Deno or Bun, as it
allows to use the built-in `fetch()` method and `WebSocket` object,
instead of using the `xmlhttprequest-ssl` and `ws` Node.js packages.

Related: socketio/socket.io-deno#12

This feature also comes with the ability to exclude the code related to
unused transports (a.k.a. "tree-shaking"):

```js
import { SocketWithoutUpgrade, WebSocket } from "engine.io-client";

const socket = new SocketWithoutUpgrade({
  transports: [WebSocket]
});
```

In that case, the code related to HTTP long-polling and WebTransport
will be excluded from the final bundle.

Related: socketio/socket.io#4393
@darrachequesne darrachequesne added this to the socket.io-client@next milestone Sep 18, 2024
@darrachequesne
Copy link
Member

For future readers:

You can now provide an array of transport implementations:

import { io } from "socket.io-client";
import { Fetch, WebSocket } from "engine.io-client";

const socket = io({
  transports: [Fetch, WebSocket]
});

Reference: https://socket.io/docs/v4/client-options/#transports

Implemented in socketio/engine.io-client@b11763b and socketio/engine.io-client@f4d898e, included in engine.io-client@6.6.0 and socket.io-client@4.8.0.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants