unxhr: XMLHttpRequest Emulation for Node.js

1.2.0 · active · verified Tue Apr 21

`unxhr` is a Node.js library that provides an emulation of the browser's native `XMLHttpRequest` object, enabling both synchronous and asynchronous HTTP requests within Node.js environments. Currently at version 1.2.0, its release cadence is moderate, with recent updates primarily focused on bug fixes and infrastructure improvements. The project is a fork of the original `XMLHttpRequest` package, specifically developed to achieve compliance with the XMLHttpRequest Level 2 specifications. Key differentiators include its complete lack of external dependencies, support for standard HTTP methods (GET, POST, PUT, DELETE), handling of binary data through JavaScript typed arrays, automatic redirection following, and limited support for the `file://` protocol. It serves as a bridge for codebases that expect browser-like XHR behavior in a Node.js context, despite some inherent limitations compared to a full browser implementation.

Common errors

Warnings

Install

Imports

Quickstart

Demonstrates basic asynchronous HTTP GET request using `unxhr`'s `XMLHttpRequest` emulation, including event handling for response and errors, wrapped in a Promise.

const XMLHttpRequest = require('unxhr').XMLHttpRequest;

async function makeRequest() {
  return new Promise((resolve, reject) => {
    const xhr = new XMLHttpRequest();
    xhr.open('GET', 'https://jsonplaceholder.typicode.com/posts/1', true); // true for async

    xhr.onreadystatechange = () => {
      if (xhr.readyState === 4) {
        if (xhr.status >= 200 && xhr.status < 300) {
          try {
            resolve(JSON.parse(xhr.responseText));
          } catch (e) {
            reject(new Error('Failed to parse JSON response: ' + e.message));
          }
        } else {
          reject(new Error(`Request failed with status ${xhr.status}: ${xhr.statusText}`));
        }
      }
    };

    xhr.onerror = () => {
      reject(new Error('Network error or connection refused.'));
    };

    xhr.send();
  });
}

makeRequest()
  .then(data => console.log('Fetched data:', data))
  .catch(error => console.error('Error during request:', error));

// Example of a synchronous request (use with extreme caution due to blocking nature)
// console.log('\nStarting synchronous request (will block event loop)...');
// const syncXhr = new XMLHttpRequest();
// try {
//   syncXhr.open('GET', 'https://jsonplaceholder.typicode.com/todos/1', false); // false for sync
//   syncXhr.send(null);
//   if (syncXhr.status === 200) {
//     console.log('Synchronous Response:', JSON.parse(syncXhr.responseText));
//   } else {
//     console.error('Synchronous Error:', syncXhr.status, syncXhr.statusText);
//   }
// } catch (e) {
//   console.error('Synchronous Request Failed:', e);
// }
// console.log('Synchronous request finished.');

view raw JSON →