On this page

C

http.ClientRequest

History
class http.ClientRequest extends http.OutgoingMessage

This object is created internally and returned from http.request(). It represents an in-progress request whose header has already been queued. The header is still mutable using the setHeader(name, value), getHeader(name), removeHeader(name) API. The actual header will be sent along with the first data chunk or when calling request.end().

To get the response, add a listener for 'response' to the request object. 'response' will be emitted from the request object when the response headers have been received. The 'response' event is executed with one argument which is an instance of http.IncomingMessage.

During the 'response' event, one can add listeners to the response object; particularly to listen for the 'data' event.

If no 'response' handler is added, then the response will be entirely discarded. However, if a 'response' event handler is added, then the data from the response object must be consumed, either by calling response.read() whenever there is a 'readable' event, or by adding a 'data' handler, or by calling the .resume() method. Until the data is consumed, the 'end' event will not fire. Also, until the data is read it will consume memory that can eventually lead to a 'process out of memory' error.

For backward compatibility, res will only emit 'error' if there is an 'error' listener registered.

Set Content-Length header to limit the response body size. If response.strictContentLength is set to true, mismatching the Content-Length header value will result in an Error being thrown, identified by code: 'ERR_HTTP_CONTENT_LENGTH_MISMATCH'.

Content-Length value should be in bytes, not characters. Use Buffer.byteLength() to determine the length of the body in bytes.

E

abort

History
Stability: 0Deprecated. Listen for the 'close' event instead.

Emitted when the request has been aborted by the client. This event is only emitted on the first call to abort().

E

close

History

Indicates that the request is completed, or its underlying connection was terminated prematurely (before the response completion).

E

connect

History
Attributes

Emitted each time a server responds to a request with a CONNECT method. If this event is not being listened for, clients receiving a CONNECT method will have their connections closed.

This event is guaranteed to be passed an instance of the net.Socket class, a subclass of stream.Duplex, unless the user specifies a socket type other than net.Socket.

A client and server pair demonstrating how to listen for the 'connect' event:

import { createServer, request } from 'node:http';
import { connect } from 'node:net';
import { URL } from 'node:url';

// Create an HTTP tunneling proxy
const proxy = createServer((req, res) => {
  res.writeHead(200, { 'Content-Type': 'text/plain' });
  res.end('okay');
});
proxy.on('connect', (req, clientSocket, head) => {
  // Connect to an origin server
  const { port, hostname } = new URL(`http://${req.url}`);
  const serverSocket = connect(port || 80, hostname, () => {
    clientSocket.write('HTTP/1.1 200 Connection Established\r\n' +
                    'Proxy-agent: Node.js-Proxy\r\n' +
                    '\r\n');
    serverSocket.write(head);
    serverSocket.pipe(clientSocket);
    clientSocket.pipe(serverSocket);
  });
});

// Now that proxy is running
proxy.listen(1337, '127.0.0.1', () => {

  // Make a request to a tunneling proxy
  const options = {
    port: 1337,
    host: '127.0.0.1',
    method: 'CONNECT',
    path: 'www.google.com:80',
  };

  const req = request(options);
  req.end();

  req.on('connect', (res, socket, head) => {
    console.log('got connected!');

    // Make a request over an HTTP tunnel
    socket.write('GET / HTTP/1.1\r\n' +
                 'Host: www.google.com:80\r\n' +
                 'Connection: close\r\n' +
                 '\r\n');
    socket.on('data', (chunk) => {
      console.log(chunk.toString());
    });
    socket.on('end', () => {
      proxy.close();
    });
  });
});
const http = require('node:http');
const net = require('node:net');
const { URL } = require('node:url');

// Create an HTTP tunneling proxy
const proxy = http.createServer((req, res) => {
  res.writeHead(200, { 'Content-Type': 'text/plain' });
  res.end('okay');
});
proxy.on('connect', (req, clientSocket, head) => {
  // Connect to an origin server
  const { port, hostname } = new URL(`http://${req.url}`);
  const serverSocket = net.connect(port || 80, hostname, () => {
    clientSocket.write('HTTP/1.1 200 Connection Established\r\n' +
                    'Proxy-agent: Node.js-Proxy\r\n' +
                    '\r\n');
    serverSocket.write(head);
    serverSocket.pipe(clientSocket);
    clientSocket.pipe(serverSocket);
  });
});

// Now that proxy is running
proxy.listen(1337, '127.0.0.1', () => {

  // Make a request to a tunneling proxy
  const options = {
    port: 1337,
    host: '127.0.0.1',
    method: 'CONNECT',
    path: 'www.google.com:80',
  };

  const req = http.request(options);
  req.end();

  req.on('connect', (res, socket, head) => {
    console.log('got connected!');

    // Make a request over an HTTP tunnel
    socket.write('GET / HTTP/1.1\r\n' +
                 'Host: www.google.com:80\r\n' +
                 'Connection: close\r\n' +
                 '\r\n');
    socket.on('data', (chunk) => {
      console.log(chunk.toString());
    });
    socket.on('end', () => {
      proxy.close();
    });
  });
});
E

continue

History

Emitted when the server sends a '100 Continue' HTTP response, usually because the request contained 'Expect: 100-continue'. This is an instruction that the client should send the request body.

E

finish

History

Emitted when the request has been sent. More specifically, this event is emitted when the last segment of the request headers and body have been handed off to the operating system for transmission over the network. It does not imply that the server has received anything yet.

E

information

History
Attributes
info:Object
httpVersion:string
httpVersionMajor:integer
httpVersionMinor:integer
statusCode:integer
statusMessage:string
headers:Object
rawHeaders:string[]

Emitted when the server sends a 1xx intermediate response (excluding 101 Upgrade). The listeners of this event will receive an object containing the HTTP version, status code, status message, key-value headers object, and array with the raw header names followed by their respective values.

import { request } from 'node:http';

const options = {
  host: '127.0.0.1',
  port: 8080,
  path: '/length_request',
};

// Make a request
const req = request(options);
req.end();

req.on('information', (info) => {
  console.log(`Got information prior to main response: ${info.statusCode}`);
});
const http = require('node:http');

const options = {
  host: '127.0.0.1',
  port: 8080,
  path: '/length_request',
};

// Make a request
const req = http.request(options);
req.end();

req.on('information', (info) => {
  console.log(`Got information prior to main response: ${info.statusCode}`);
});

101 Upgrade statuses do not fire this event due to their break from the traditional HTTP request/response chain, such as web sockets, in-place TLS upgrades, or HTTP 2.0. To be notified of 101 Upgrade notices, listen for the 'upgrade' event instead.

E

response

History
Attributes

Emitted when a response is received to this request. This event is emitted only once.

E

socket

History
Attributes

This event is guaranteed to be passed an instance of the net.Socket class, a subclass of stream.Duplex, unless the user specifies a socket type other than net.Socket.

E

timeout

History

Emitted when the underlying socket times out from inactivity. This only notifies that the socket has been idle. The request must be destroyed manually.

See also: request.setTimeout().

E

upgrade

History
Attributes

Emitted each time a server responds to a request with an upgrade. If this event is not being listened for and the response status code is 101 Switching Protocols, clients receiving an upgrade header will have their connections closed.

This event is guaranteed to be passed an instance of the net.Socket class, a subclass of stream.Duplex, unless the user specifies a socket type other than net.Socket.

A client server pair demonstrating how to listen for the 'upgrade' event.

import http from 'node:http';
import process from 'node:process';

// Create an HTTP server
const server = http.createServer((req, res) => {
  res.writeHead(200, { 'Content-Type': 'text/plain' });
  res.end('okay');
});
server.on('upgrade', (req, stream, head) => {
  stream.write('HTTP/1.1 101 Web Socket Protocol Handshake\r\n' +
               'Upgrade: WebSocket\r\n' +
               'Connection: Upgrade\r\n' +
               '\r\n');

  stream.pipe(stream); // echo back
});

// Now that server is running
server.listen(1337, '127.0.0.1', () => {

  // make a request
  const options = {
    port: 1337,
    host: '127.0.0.1',
    headers: {
      'Connection': 'Upgrade',
      'Upgrade': 'websocket',
    },
  };

  const req = http.request(options);
  req.end();

  req.on('upgrade', (res, stream, upgradeHead) => {
    console.log('got upgraded!');
    stream.end();
    process.exit(0);
  });
});
const http = require('node:http');

// Create an HTTP server
const server = http.createServer((req, res) => {
  res.writeHead(200, { 'Content-Type': 'text/plain' });
  res.end('okay');
});
server.on('upgrade', (req, stream, head) => {
  stream.write('HTTP/1.1 101 Web Socket Protocol Handshake\r\n' +
               'Upgrade: WebSocket\r\n' +
               'Connection: Upgrade\r\n' +
               '\r\n');

  stream.pipe(stream); // echo back
});

// Now that server is running
server.listen(1337, '127.0.0.1', () => {

  // make a request
  const options = {
    port: 1337,
    host: '127.0.0.1',
    headers: {
      'Connection': 'Upgrade',
      'Upgrade': 'websocket',
    },
  };

  const req = http.request(options);
  req.end();

  req.on('upgrade', (res, stream, upgradeHead) => {
    console.log('got upgraded!');
    stream.end();
    process.exit(0);
  });
});
M

request.abort

History
request.abort(): void
Stability: 0Deprecated: Use request.destroy() instead.

Marks the request as aborting. Calling this will cause remaining data in the response to be dropped and the socket to be destroyed.

P

request.aborted

History
Stability: 0Deprecated. Check request.destroyed instead.
Type:boolean

The request.aborted property will be true if the request has been aborted.

P

request.connection

History
Stability: 0Deprecated. Use request.socket.

See request.socket.

M

request.cork

History
request.cork(): void

See writable.cork().

request.end(data?, encoding?, callback?): this
Attributes
encoding:string
callback:Function
Returns:this

Finishes sending the request. If any parts of the body are unsent, it will flush them to the stream. If the request is chunked, this will send the terminating '0\r\n\r\n'.

If data is specified, it is equivalent to calling request.write(data, encoding) followed by request.end(callback).

If callback is specified, it will be called when the request stream is finished.

request.destroy(error?): this
Attributes
error:Error
Optional, an error to emit with 'error' event.
Returns:this

Destroy the request. Optionally emit an 'error' event, and emit a 'close' event. Calling this will cause remaining data in the response to be dropped, and the socket to be destroyed if used, or returned to the corresponding Agent pool otherwise if possible.

See writable.destroy() for further details.

P

request.destroyed

History
Type:boolean

Is true after request.destroy() has been called.

See writable.destroyed for further details.

P

request.finished

History
Stability: 0Deprecated. Use request.writableEnded.
Type:boolean

The request.finished property will be true if request.end() has been called. request.end() will automatically be called if the request was initiated via http.get().

M

request.flushHeaders

History
request.flushHeaders(): void

Flushes the request headers.

For efficiency reasons, Node.js normally buffers the request headers until request.end() is called or the first chunk of request data is written. It then tries to pack the request headers and data into a single TCP packet.

That's usually desired (it saves a TCP round-trip), but not when the first data is not sent until possibly much later. request.flushHeaders() bypasses the optimization and kickstarts the request.

M

request.getHeader

History
request.getHeader(name): any
Attributes
name:string
Returns:any

Reads out a header on the request. The name is case-insensitive. The type of the return value depends on the arguments provided to request.setHeader().

request.setHeader('content-type', 'text/html');
request.setHeader('Content-Length', Buffer.byteLength(body));
request.setHeader('Cookie', ['type=ninja', 'language=javascript']);
const contentType = request.getHeader('Content-Type');
// 'contentType' is 'text/html'
const contentLength = request.getHeader('Content-Length');
// 'contentLength' is of type number
const cookie = request.getHeader('Cookie');
// 'cookie' is of type string[]
M

request.getHeaderNames

History
request.getHeaderNames(): string[]
Returns:string[]

Returns an array containing the unique names of the current outgoing headers. All header names are lowercase.

request.setHeader('Foo', 'bar');
request.setHeader('Cookie', ['foo=bar', 'bar=baz']);

const headerNames = request.getHeaderNames();
// headerNames === ['foo', 'cookie']
M

request.getHeaders

History
request.getHeaders(): Object
Returns:Object

Returns a shallow copy of the current outgoing headers. Since a shallow copy is used, array values may be mutated without additional calls to various header-related http module methods. The keys of the returned object are the header names and the values are the respective header values. All header names are lowercase.

The object returned by the request.getHeaders() method does not prototypically inherit from the JavaScript Object. This means that typical Object methods such as obj.toString(), obj.hasOwnProperty(), and others are not defined and will not work.

request.setHeader('Foo', 'bar');
request.setHeader('Cookie', ['foo=bar', 'bar=baz']);

const headers = request.getHeaders();
// headers === { foo: 'bar', 'cookie': ['foo=bar', 'bar=baz'] }
M

request.getRawHeaderNames

History
request.getRawHeaderNames(): string[]
Returns:string[]

Returns an array containing the unique names of the current outgoing raw headers. Header names are returned with their exact casing being set.

request.setHeader('Foo', 'bar');
request.setHeader('Set-Cookie', ['foo=bar', 'bar=baz']);

const headerNames = request.getRawHeaderNames();
// headerNames === ['Foo', 'Set-Cookie']
M

request.hasHeader

History
request.hasHeader(name): boolean
Attributes
name:string
Returns:boolean

Returns true if the header identified by name is currently set in the outgoing headers. The header name matching is case-insensitive.

Type?:number
Default: 2000

Limits maximum response headers count. If set to 0, no limit will be applied.

P

request.path

History
Type:string
The request path.
P

request.method

History
Type:string
The request method.
P

request.host

History
Type:string
The request host.
P

request.protocol

History
Type:string
The request protocol.
M

request.removeHeader

History
request.removeHeader(name): void
Attributes
name:string

Removes a header that's already defined into headers object.

P

request.reusedSocket

History
Type:boolean
Whether the request is sent through a reused socket.

When sending request through a keep-alive enabled agent, the underlying socket might be reused. But if server closes connection at unfortunate time, client may run into a 'ECONNRESET' error.

import http from 'node:http';
const agent = new http.Agent({ keepAlive: true });

// Server has a 5 seconds keep-alive timeout by default
http
  .createServer((req, res) => {
    res.write('hello\n');
    res.end();
  })
  .listen(3000);

setInterval(() => {
  // Adapting a keep-alive agent
  http.get('http://localhost:3000', { agent }, (res) => {
    res.on('data', (data) => {
      // Do nothing
    });
  });
}, 5000); // Sending request on 5s interval so it's easy to hit idle timeout
const http = require('node:http');
const agent = new http.Agent({ keepAlive: true });

// Server has a 5 seconds keep-alive timeout by default
http
  .createServer((req, res) => {
    res.write('hello\n');
    res.end();
  })
  .listen(3000);

setInterval(() => {
  // Adapting a keep-alive agent
  http.get('http://localhost:3000', { agent }, (res) => {
    res.on('data', (data) => {
      // Do nothing
    });
  });
}, 5000); // Sending request on 5s interval so it's easy to hit idle timeout

By marking a request whether it reused socket or not, we can do automatic error retry base on it.

import http from 'node:http';
const agent = new http.Agent({ keepAlive: true });

function retriableRequest() {
  const req = http
    .get('http://localhost:3000', { agent }, (res) => {
      // ...
    })
    .on('error', (err) => {
      // Check if retry is needed
      if (req.reusedSocket && err.code === 'ECONNRESET') {
        retriableRequest();
      }
    });
}

retriableRequest();
const http = require('node:http');
const agent = new http.Agent({ keepAlive: true });

function retriableRequest() {
  const req = http
    .get('http://localhost:3000', { agent }, (res) => {
      // ...
    })
    .on('error', (err) => {
      // Check if retry is needed
      if (req.reusedSocket && err.code === 'ECONNRESET') {
        retriableRequest();
      }
    });
}

retriableRequest();
M

request.setHeader

History
request.setHeader(name, value): void
Attributes
name:string
value:any

Sets a single header value for headers object. If this header already exists in the to-be-sent headers, its value will be replaced. Use an array of strings here to send multiple headers with the same name. Non-string values will be stored without modification. Therefore, request.getHeader() may return non-string values. However, the non-string values will be converted to strings for network transmission.

or

When the value is a string an exception will be thrown if it contains characters outside the latin1 encoding.

If you need to pass UTF-8 characters in the value please encode the value using the RFC 8187 standard.

const filename = 'Rock 🎵.txt';
request.setHeader('Content-Disposition', `attachment; filename*=utf-8''${encodeURIComponent(filename)}`);
M

request.setNoDelay

History
request.setNoDelay(noDelay?): void
Attributes
noDelay:boolean

Once a socket is assigned to this request and is connected socket.setNoDelay() will be called.

M

request.setSocketKeepAlive

History
request.setSocketKeepAlive(enable?, initialDelay?): void
Attributes
enable:boolean
initialDelay:number

Once a socket is assigned to this request and is connected socket.setKeepAlive() will be called.

request.setTimeout(timeout, callback?): http.ClientRequest
Attributes
timeout:number
Milliseconds before a request times out.
callback:Function
Optional function to be called when a timeout occurs. Same as binding to the 'timeout' event.

Once a socket is assigned to this request and is connected socket.setTimeout() will be called.

P

request.socket

History

Reference to the underlying socket. Usually users will not want to access this property. In particular, the socket will not emit 'readable' events because of how the protocol parser attaches to the socket.

import http from 'node:http';
const options = {
  host: 'www.google.com',
};
const req = http.get(options);
req.end();
req.once('response', (res) => {
  const ip = req.socket.localAddress;
  const port = req.socket.localPort;
  console.log(`Your IP address is ${ip} and your source port is ${port}.`);
  // Consume response object
});
const http = require('node:http');
const options = {
  host: 'www.google.com',
};
const req = http.get(options);
req.end();
req.once('response', (res) => {
  const ip = req.socket.localAddress;
  const port = req.socket.localPort;
  console.log(`Your IP address is ${ip} and your source port is ${port}.`);
  // Consume response object
});

This property is guaranteed to be an instance of the net.Socket class, a subclass of stream.Duplex, unless the user specified a socket type other than net.Socket.

M

request.uncork

History
request.uncork(): void

See writable.uncork().

P

request.writableEnded

History
Type:boolean

Is true after request.end() has been called. This property does not indicate whether the data has been flushed, for this use request.writableFinished instead.

P

request.writableFinished

History
Type:boolean

Is true if all data has been flushed to the underlying system, immediately before the 'finish' event is emitted.

request.write(chunk, encoding?, callback?): boolean
Attributes
encoding:string
callback:Function
Returns:boolean

Sends a chunk of the body. This method can be called multiple times. If no Content-Length is set, data will automatically be encoded in HTTP Chunked transfer encoding, so that server knows when the data ends. The Transfer-Encoding: chunked header is added. Calling request.end() is necessary to finish sending the request.

The encoding argument is optional and only applies when chunk is a string. Defaults to 'utf8'.

The callback argument is optional and will be called when this chunk of data is flushed, but only if the chunk is non-empty.

Returns true if the entire data was flushed successfully to the kernel buffer. Returns false if all or part of the data was queued in user memory. 'drain' will be emitted when the buffer is free again.

When write function is called with empty string or buffer, it does nothing and waits for more input.