Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/strophe/strophejs/llms.txt

Use this file to discover all available pages before exploring further.

BOSH (Bidirectional-streams Over Synchronous HTTP) is the transport protocol defined in XEP-0124 and XEP-0206 that lets XMPP clients communicate with servers over ordinary HTTP requests instead of a persistent TCP socket. Strophe.js selects BOSH automatically whenever you pass an http:// or https:// URL — or any path that does not begin with ws: or wss: — to new Strophe.Connection().

When to Use BOSH

Use BOSH when…

  • Corporate firewalls or proxies block WebSocket upgrades
  • You need broad compatibility with legacy infrastructure
  • Server-side session prebinding is required (XEP-0124 attach)
  • You want built-in keepalive via sessionStorage

Prefer WebSocket when…

  • Low latency and high message throughput matter
  • Your server and network infrastructure support WebSocket
  • You do not need HTTP-proxy compatibility

Connection URL Format

Strophe.js detects BOSH from the URL scheme. Any URL beginning with http:// or https://, or a relative path, is treated as a BOSH endpoint.
http://xmpp.example.com:5280/http-bind
https://xmpp.example.com:5281/http-bind
/xmpp-httpbind
/http-bind/
Most XMPP servers expose the BOSH endpoint at either /http-bind or /xmpp-httpbind. Check your server’s documentation — for example, ejabberd uses /bosh by default while Prosody uses /http-bind.

Basic BOSH Connection

import { Strophe } from 'strophejs';

const BOSH_SERVICE = 'https://xmpp.example.com:5281/http-bind';

const connection = new Strophe.Connection(BOSH_SERVICE);

connection.connect('user@example.com', 'password', (status, condition) => {
  if (status === Strophe.Status.CONNECTING) {
    console.log('Connecting via BOSH…');
  } else if (status === Strophe.Status.CONNECTED) {
    console.log('Connected!');
  } else if (status === Strophe.Status.CONNFAIL) {
    console.error('Connection failed:', condition);
  } else if (status === Strophe.Status.DISCONNECTED) {
    console.log('Disconnected.');
  }
});
Strophe.js picks up the http:// scheme and instantiates a Bosh transport internally. No extra configuration is needed for a straightforward connection.

BOSH-Specific Connection Options

All options below are passed as the second argument to new Strophe.Connection(service, options).

sync — Synchronous Requests

By default all BOSH HTTP requests are asynchronous. Setting sync: true makes Strophe.js use synchronous XMLHttpRequest calls instead. This is occasionally useful in Node.js scripts or unit tests but should never be used in a browser UI because it blocks the event loop.
const connection = new Strophe.Connection('/http-bind/', { sync: true });

// You can also toggle it on an existing connection
connection.options.sync = false;

customHeaders — Extra HTTP Headers

Pass an object whose keys are header names and values are header values. Strophe.js sets these headers on every outgoing XMLHttpRequest.
const connection = new Strophe.Connection('/http-bind/', {
  customHeaders: {
    'X-App-Token': 'my-app-token',
    'X-Client-Version': '2.0',
  },
});

keepalive — Persist Sessions Across Reloads

When keepalive is true, Strophe.js serialises the BOSH session tokens (jid, rid, sid) into sessionStorage after every request. On the next page load you can restore the session with connection.restore() without re-authenticating.
const connection = new Strophe.Connection('/http-bind/', { keepalive: true });
See the Session Management guide for how to use restore().

cookies — Include Cookies in Requests

Pass a map of cookie definitions to have Strophe.js attach them to every BOSH HTTP request. Note that cookies set this way are scoped to the same domain as the page — cross-domain cookies must be set server-side.
const connection = new Strophe.Connection('/http-bind/', {
  cookies: {
    mySession: {
      value: 'abc123',
      domain: '.example.com',
      path: '/',
    },
  },
});

withCredentials — Cross-Origin Cookies

Set withCredentials: true to include cookies when making cross-origin BOSH requests. The BOSH server must respond with Access-Control-Allow-Credentials: true and a concrete (non-wildcard) Access-Control-Allow-Origin header for this to work.
const connection = new Strophe.Connection('https://xmpp.example.com/http-bind', {
  withCredentials: true,
});
Using withCredentials with a wildcard Access-Control-Allow-Origin: * header will cause the browser to reject the response. Always pair it with a specific origin on the server side.

BOSH Keepalive Example

import { Strophe } from 'strophejs';

const connection = new Strophe.Connection('/http-bind/', { keepalive: true });

function onConnect(status: number, condition?: string | null) {
  if (status === Strophe.Status.CONNECTED) {
    console.log('Connected as', connection.jid);
  } else if (status === Strophe.Status.ATTACHED) {
    console.log('Session restored for', connection.jid);
  } else if (status === Strophe.Status.DISCONNECTED) {
    console.log('Disconnected.');
  }
}

// Try to restore a previously cached session first.
// Falls back to a full login if no cached session exists.
try {
  connection.restore(undefined, onConnect);
} catch (e) {
  if ((e as Error).name === 'StropheSessionError') {
    connection.connect('user@example.com', 'password', onConnect);
  } else {
    throw e;
  }
}

Bosh Class Internals

The Bosh class is the internal transport object stored at connection._proto when BOSH is active. You generally do not interact with it directly, but understanding its properties helps with debugging and advanced configuration.
PropertyDefaultDescription
ridrandom 32-bit intThe current BOSH request ID, incremented with each body sent
sidnullSession identifier assigned by the server on first connection
hold1Number of connections the server holds open simultaneously
wait60Seconds the server waits before returning an empty response
window5Allowed range of valid request IDs (pipelining window)
errors0Consecutive request error count; disconnects after 5 errors
inactivitynullMax inactivity seconds the server will tolerate (set by server)
stripfalseStrip the <body> wrapper from xmlInput/xmlOutput callbacks

Stripping the <body> Wrapper

Every BOSH stanza is wrapped in a <body> element defined by the HTTPBIND namespace. By default Strophe.js passes the full <body> element to your xmlInput and xmlOutput callbacks. If you prefer to receive individual XMPP stanzas directly, set strip to true:
// Option 1: set on the prototype to affect all BOSH connections
Strophe.Bosh.prototype.strip = true;

// Option 2: set on the specific connection's proto instance
const connection = new Strophe.Connection('/http-bind/');
(connection._proto as Strophe.Bosh).strip = true;

Timeout Configuration

BOSH timeouts are controlled by two multipliers on the Strophe namespace. Both values are multiplied against the negotiated wait time to derive actual timeouts.
PropertyDefault multiplierDescription
Strophe.TIMEOUT1.1Primary timeout multiplier — triggers request restart when exceeded
Strophe.SECONDARY_TIMEOUT0.1Secondary timeout multiplier — applies when a request is already considered “dead”
// Increase the primary timeout to 1.5× the wait value
Strophe.TIMEOUT = 1.5;

// Increase the secondary timeout to 0.2× the wait value
Strophe.SECONDARY_TIMEOUT = 0.2;
These settings take effect globally for all BOSH connections created after the change. Adjust them when connecting to servers with a non-default wait value or when operating over high-latency networks.

Connection Pooling: hold and wait

The default hold=1 means Strophe.js keeps at most one HTTP request open on the server at a time. The server holds the request for up to wait=60 seconds and responds either with XMPP stanzas to deliver or an empty body. This makes BOSH behave like a long-poll connection. You can pass wait and hold overrides to connection.connect():
// Use a shorter wait time (30 s) — useful on flaky networks
connection.connect('user@example.com', 'password', onConnect, 30, 1);
Increasing hold above 1 or decreasing wait below the default can increase server load. Most deployments work well with the defaults.

CORS and Same-Origin Restrictions

Browsers enforce CORS on XMLHttpRequest. If your Strophe.js client is served from a different origin than the BOSH endpoint, the XMPP server must include appropriate Access-Control-Allow-Origin headers. Without these headers the browser will block all BOSH requests and the connection will fail immediately. When in doubt, proxy the BOSH endpoint through the same origin as your web application.

Build docs developers (and LLMs) love