HTTP
Исходный код: lib/http.js
Этот модуль, содержащий клиентскую и серверную части, можно импортировать с помощью require('node:http') (CommonJS) или import * as http from 'node:http' (модуль ES).
Интерфейсы HTTP в Node.js разработаны для поддержки многих возможностей протокола, использование которых традиционно было затруднено. В частности, это большие сообщения, которые могут быть закодированы с помощью чанков. Интерфейс устроен так, чтобы никогда не буферизовать целые запросы или ответы, благодаря чему пользователь может передавать данные потоком.
Заголовки HTTP-сообщений представлены объектом следующего вида:
{ "content-length": "123",
"content-type": "text/plain",
"connection": "keep-alive",
"host": "example.com",
"accept": "*/*" } copy Ключи приводятся к нижнему регистру. Значения не изменяются.
Чтобы поддерживать весь спектр возможных HTTP-приложений, API HTTP в Node.js имеет очень низкий уровень абстракции. Он работает только с обработкой потоков и разбором сообщений. Он разбирает сообщение на заголовки и тело, но не разбирает сами заголовки или тело.
Подробнее об обработке повторяющихся заголовков см. в разделе message.headers.
Исходные заголовки в том виде, в котором они были получены, сохраняются в свойстве rawHeaders, которое является массивом [key, value, key2, value2, ...]. Например, предыдущий объект заголовков сообщения мог бы иметь список rawHeaders следующего вида:
[ 'ConTent-Length', '123456', 'content-LENGTH', '123', 'content-type', 'text/plain', 'CONNECTION', 'keep-alive', 'Host', 'example.com', 'accepT', '*/*' ] copy
Класс: http.Agent
Agent отвечает за управление постоянством и повторным использованием соединений для HTTP-клиентов. Он поддерживает очередь ожидающих запросов для заданных хоста и порта, повторно используя одно соединение сокета для каждого запроса, пока очередь не опустеет. После этого сокет либо уничтожается, либо помещается в пул, где хранится для повторного использования в запросах к тому же хосту и порту. Уничтожение сокета или помещение его в пул зависит от keepAlive параметра.
Для соединений в пуле включена функция TCP Keep-Alive, однако серверы всё равно могут закрывать неактивные соединения. В этом случае такие соединения будут удалены из пула, а при поступлении нового HTTP-запроса к этому хосту и порту будет установлено новое соединение. Серверы также могут запрещать отправку нескольких запросов через одно соединение. В таком случае соединение придётся создавать заново для каждого запроса, и его нельзя будет поместить в пул. Agent всё равно будет отправлять запросы этому серверу, но каждый из них будет выполняться через новое соединение.
Если клиент или сервер закрывает соединение, оно удаляется из пула. Все неиспользуемые сокеты в пуле будут освобождены с помощью unref, чтобы процесс Node.js не продолжал работать при отсутствии незавершённых запросов (см. socket.unref()).
Рекомендуется destroy() экземпляр Agent, когда он больше не используется, поскольку неиспользуемые сокеты расходуют ресурсы ОС.
Сокеты удаляются из агента при возникновении события 'close' или 'agentRemove'. Если нужно надолго оставить открытым один HTTP-запрос, не сохраняя его в агенте, можно сделать примерно следующее:
http.get(options, (res) => {
// Do stuff
}).on('socket', (socket) => {
socket.emit('agentRemove');
}); copy Агент также можно использовать для отдельного запроса. Если передать {agent: false} в качестве параметра функциям http.get() или http.request(), для клиентского соединения будет использоваться одноразовый Agent с параметрами по умолчанию.
agent:false:
http.get({
hostname: 'localhost',
port: 80,
path: '/',
agent: false, // Create a new agent just for this one request
}, (res) => {
// Do stuff with response
}); copy
new Agent([options])
-
options<Object> Набор настраиваемых параметров агента. Может содержать следующие поля:-
keepAlive<boolean> Сохранять сокеты открытыми, даже если нет незавершённых запросов, чтобы их можно было использовать для будущих запросов без повторного установления TCP-соединения. Не путать со значениемkeep-aliveзаголовкаConnection. При использовании агента заголовокConnection: keep-aliveотправляется всегда, кроме случаев, когда явно указан заголовокConnectionили параметрыkeepAliveиmaxSocketsсоответственно установлены вfalseиInfinity. В таком случае будет использоватьсяConnection: close. По умолчанию:false. -
keepAliveMsecs<number> При использовании параметраkeepAliveзадаёт начальную задержку для пакетов TCP Keep-Alive. Игнорируется, если параметрkeepAliveимеет значениеfalseилиundefined. По умолчанию:1000. -
maxSockets<number> Максимальное количество сокетов, разрешённое для одного хоста. Если для одного хоста открывается несколько одновременных соединений, для каждого запроса будет использоваться новый сокет, пока не будет достигнуто значениеmaxSockets. Если хост попытается открыть больше соединений, чемmaxSockets, дополнительные запросы попадут в очередь ожидания и перейдут в состояние активного соединения после завершения одного из существующих соединений. Это гарантирует, что от одного хоста одновременно будет открыто не болееmaxSocketsсоединений. По умолчанию:Infinity. -
maxTotalSockets<number> Максимальное общее количество сокетов, разрешённое для всех хостов. Для каждого запроса будет использоваться новый сокет, пока не будет достигнуто максимальное значение. По умолчанию:Infinity. -
maxFreeSockets<number> Максимальное количество сокетов для одного хоста, которые могут оставаться открытыми в свободном состоянии. Имеет значение, только еслиkeepAliveустановлено вtrue. По умолчанию:256. -
scheduling<string> Стратегия планирования, применяемая при выборе следующего свободного сокета. Может иметь значение'fifo'или'lifo'. Основное различие между стратегиями планирования состоит в том, что'lifo'выбирает сокет, использовавшийся последним, а'fifo'— сокет, использовавшийся давнее всего. При низкой частоте запросов'lifo'снижает риск выбора сокета, который сервер мог закрыть из-за бездействия. При высокой частоте запросов'fifo'максимально увеличивает количество открытых сокетов, а'lifo'поддерживает его как можно меньшим. По умолчанию:'lifo'. -
timeout<number> Тайм-аут сокета в миллисекундах. Это значение задаёт тайм-аут при создании сокета.
-
Также поддерживаются options из socket.connect().
Чтобы настроить любой из них, необходимо создать пользовательский экземпляр http.Agent.
Модули JavaScript
import { Agent, request } from 'node:http';
const keepAliveAgent = new Agent({ keepAlive: true });
options.agent = keepAliveAgent;
request(options, onResponseCallback);CommonJS
const http = require('node:http');
const keepAliveAgent = new http.Agent({ keepAlive: true });
options.agent = keepAliveAgent;
http.request(options, onResponseCallback);
agent.createConnection(options[, callback])
-
options<Object> Параметры с данными соединения. Формат параметров см. в разделеnet.createConnection() -
callback<Function> Функция обратного вызова, получающая созданный сокет - Возвращает: <stream.Duplex>
Создаёт сокет/поток для использования в HTTP-запросах.
По умолчанию эта функция совпадает с net.createConnection(). Однако пользовательские агенты могут переопределить этот метод, если требуется большая гибкость.
Сокет/поток можно передать одним из двух способов: вернуть его из этой функции или передать в callback.
Гарантируется, что этот метод вернёт экземпляр класса <net.Socket>, подкласса <stream.Duplex>, если только пользователь не укажет тип сокета, отличный от <net.Socket>.
Сигнатура callback — (err, stream).
agent.keepSocketAlive(socket)
-
socket<stream.Duplex>
Вызывается, когда socket отсоединяется от запроса и может быть сохранён Agent. Поведение по умолчанию:
socket.setKeepAlive(true, this.keepAliveMsecs); socket.unref(); return true; copy
Этот метод можно переопределить в конкретном подклассе Agent. Если метод возвращает ложное значение, сокет будет уничтожен, а не сохранён для использования со следующим запросом.
Аргумент socket может быть экземпляром <net.Socket>, подкласса <stream.Duplex>.
agent.reuseSocket(socket, request)
-
socket<stream.Duplex> -
request<http.ClientRequest>
Вызывается, когда socket подключается к request после сохранения благодаря параметрам keep-alive. Поведение по умолчанию:
socket.ref(); copy
Этот метод можно переопределить в конкретном подклассе Agent.
Аргумент socket может быть экземпляром <net.Socket>, подкласса <stream.Duplex>.
agent.destroy()
Уничтожает все сокеты, используемые в данный момент агентом.
Обычно в этом нет необходимости. Однако при использовании агента с включённым keepAlive рекомендуется явно завершить работу агента, когда он больше не нужен. В противном случае сокеты могут оставаться открытыми довольно долго, пока сервер не закроет их.
agent.freeSockets
Объект, содержащий массивы сокетов, ожидающих использования агентом при включённом keepAlive. Не изменяйте его.
Сокеты из списка freeSockets автоматически уничтожаются и удаляются из массива при событии 'timeout'.
agent.getName([options])
Возвращает уникальное имя для набора параметров запроса, чтобы определить, можно ли повторно использовать соединение. Для HTTP-агента возвращается host:port:localAddress или host:port:localAddress:family. Для HTTPS-агента имя включает CA, сертификат, шифры и другие специфичные для HTTPS/TLS параметры, определяющие возможность повторного использования сокета.
agent.maxFreeSockets
По умолчанию равно 256. Для агентов с включённым keepAlive задаёт максимальное количество сокетов, которые останутся открытыми в свободном состоянии.
agent.maxSockets
По умолчанию равно Infinity. Определяет количество одновременных сокетов, которые агент может открыть для одного источника. Источник — это значение, возвращаемое agent.getName().
agent.maxTotalSockets
По умолчанию равно Infinity. Определяет количество одновременных сокетов, которые агент может открыть. В отличие от maxSockets, этот параметр применяется ко всем источникам.
agent.requests
Объект, содержащий очереди запросов, которым ещё не назначены сокеты. Не изменяйте его.
agent.sockets
Объект, содержащий массивы сокетов, используемых в данный момент агентом. Не изменяйте его.
Класс: http.ClientRequest
- Расширяет: <http.OutgoingMessage>
Этот объект создаётся внутри системы и возвращается из http.request(). Он представляет выполняющийся запрос, заголовок которого уже помещён в очередь. Заголовок по-прежнему можно изменить с помощью API setHeader(name, value), getHeader(name), removeHeader(name). Фактический заголовок будет отправлен вместе с первой порцией данных или при вызове request.end().
Чтобы получить ответ, добавьте к объекту запроса прослушиватель события 'response'. Событие 'response' будет испущено объектом запроса после получения заголовков ответа. Обработчик события 'response' вызывается с одним аргументом — экземпляром http.IncomingMessage.
Во время события 'response' к объекту ответа можно добавить прослушиватели; в частности, чтобы прослушивать событие 'data'.
Если обработчик 'response' не добавлен, ответ будет полностью отброшен. Однако если добавлен обработчик события 'response', данные из объекта ответа необходимо обработать: вызывать response.read() при каждом событии 'readable', добавить обработчик 'data' или вызвать метод .resume(). Пока данные не будут обработаны, событие 'end' не произойдёт. Кроме того, пока данные не прочитаны, они будут занимать память, что в конечном итоге может привести к ошибке «process out of memory».
Для обеспечения обратной совместимости res будет испускать 'error' только в том случае, если зарегистрирован прослушиватель 'error'.
Задайте заголовок Content-Length, чтобы ограничить размер тела ответа. Если для response.strictContentLength задано значение true, несоответствие значения заголовка Content-Length приведёт к выбрасыванию Error с кодом code: 'ERR_HTTP_CONTENT_LENGTH_MISMATCH'.
Значение Content-Length должно указываться в байтах, а не в символах. Используйте Buffer.byteLength(), чтобы определить длину тела в байтах.
Событие: 'abort'
'close'.Испускается, когда клиент прервал запрос. Это событие испускается только при первом вызове abort().
Событие: 'close'
Указывает, что запрос завершён или базовое соединение было преждевременно разорвано (до завершения ответа).
Событие: 'connect'
-
response<http.IncomingMessage> -
socket<stream.Duplex> -
head<Buffer>
Испускается при каждом ответе сервера на запрос с методом CONNECT. Если это событие не прослушивается, соединения клиентов, получающих запрос с методом CONNECT, будут закрыты.
Гарантируется, что в это событие будет передан экземпляр класса <net.Socket>, подкласса <stream.Duplex>, если только пользователь не укажет тип сокета, отличный от <net.Socket>.
Пример взаимодействия клиента и сервера, демонстрирующий прослушивание события 'connect':
Модули JavaScript
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();
});
});
});CommonJS
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();
});
});
});Событие: 'continue'
Испускается, когда сервер отправляет HTTP-ответ «100 Continue», обычно потому, что запрос содержал «Expect: 100-continue». Это указание клиенту отправить тело запроса.
Событие: 'finish'
Испускается после отправки запроса. Точнее, это событие испускается, когда последний фрагмент заголовков и тела ответа передан операционной системе для отправки по сети. Оно не означает, что сервер уже что-либо получил.
Событие: 'information'
-
info<Object>
Испускается, когда сервер отправляет промежуточный ответ 1xx (за исключением 101 Upgrade). Прослушиватели этого события получают объект, содержащий версию HTTP, код состояния, сообщение о состоянии, объект заголовков с парами ключ-значение и массив исходных имён заголовков, за которыми следуют соответствующие им значения.
Модули JavaScript
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}`);
});CommonJS
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 это событие не испускается, поскольку они выходят за рамки традиционной цепочки запросов и ответов HTTP, например, при использовании веб-сокетов, обновлении TLS на месте или HTTP 2.0. Чтобы получать уведомления об ответах 101 Upgrade, прослушивайте событие 'upgrade'.
Событие: 'response'
-
response<http.IncomingMessage>
Испускается при получении ответа на этот запрос. Это событие испускается только один раз.
Событие: 'socket'
-
socket<stream.Duplex>
Гарантируется, что в это событие будет передан экземпляр класса <net.Socket>, подкласса <stream.Duplex>, если только пользователь не укажет тип сокета, отличный от <net.Socket>.
Событие: 'timeout'
Испускается, когда время ожидания базового сокета истекает из-за бездействия. Это лишь уведомляет о том, что сокет бездействовал. Запрос необходимо уничтожить вручную.
См. также: request.setTimeout().
Событие: 'upgrade'
-
response<http.IncomingMessage> -
socket<stream.Duplex> -
head<Buffer>
Испускается при каждом ответе сервера на запрос с обновлением протокола. Если это событие не прослушивается и код состояния ответа равен 101 Switching Protocols, соединения клиентов, получающих заголовок обновления, будут закрыты.
Гарантируется, что в это событие будет передан экземпляр класса <net.Socket>, подкласса <stream.Duplex>, если только пользователь не укажет тип сокета, отличный от <net.Socket>.
Пример взаимодействия клиента и сервера, демонстрирующий прослушивание события 'upgrade'.
Модули JavaScript
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, socket, head) => {
socket.write('HTTP/1.1 101 Web Socket Protocol Handshake\r\n' +
'Upgrade: WebSocket\r\n' +
'Connection: Upgrade\r\n' +
'\r\n');
socket.pipe(socket); // 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, socket, upgradeHead) => {
console.log('got upgraded!');
socket.end();
process.exit(0);
});
});CommonJS
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, socket, head) => {
socket.write('HTTP/1.1 101 Web Socket Protocol Handshake\r\n' +
'Upgrade: WebSocket\r\n' +
'Connection: Upgrade\r\n' +
'\r\n');
socket.pipe(socket); // 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, socket, upgradeHead) => {
console.log('got upgraded!');
socket.end();
process.exit(0);
});
});
request.abort()
request.destroy().Помечает запрос как прерываемый. Вызов этого метода приведёт к отбрасыванию оставшихся данных ответа и уничтожению сокета.
request.aborted
request.destroyed.Значение свойства request.aborted будет равно true, если запрос был прерван.
request.connection
request.socket.См. request.socket.
request.cork()
См. writable.cork().
request.end([data[, encoding]][, callback])
-
data<string> | <Buffer> | <Uint8Array> -
encoding<string> -
callback<Function> - Возвращает: <this>
Завершает отправку запроса. Если какие-либо части тела ещё не отправлены, они будут переданы в поток. Если запрос использует передачу с разбиением на блоки, будет отправлен завершающий '0\r\n\r\n'.
Если указан data, это эквивалентно вызову request.write(data, encoding), за которым следует request.end(callback).
Если указан callback, он будет вызван после завершения потока запроса.
request.destroy([error])
Уничтожает запрос. При необходимости испускает событие 'error', а также событие 'close'. Вызов этого метода приведёт к отбрасыванию оставшихся данных ответа и уничтожению сокета.
Дополнительные сведения см. в разделе writable.destroy().
request.destroyed
Равно true после вызова request.destroy().
Дополнительные сведения см. в разделе writable.destroyed.
request.finished
request.writableEnded.Значение свойства request.finished будет равно true, если был вызван request.end(). request.end() будет вызван автоматически, если запрос был инициирован через http.get().
request.flushHeaders()
Сбрасывает заголовки запроса.
Для повышения эффективности Node.js обычно буферизует заголовки запроса до вызова request.end() или записи первого фрагмента данных запроса. Затем система пытается объединить заголовки и данные запроса в один TCP-пакет.
Обычно это желательно (так экономится один цикл обмена данными TCP), но не в тех случаях, когда первые данные будут отправлены лишь через значительное время. request.flushHeaders() отключает эту оптимизацию и инициирует отправку запроса.
request.getHeader(name)
Читает заголовок запроса. Регистр имени не учитывается. Тип возвращаемого значения зависит от аргументов, переданных в 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[] copy
request.getHeaderNames()
- Возвращает: <string[]>
Возвращает массив, содержащий уникальные имена текущих исходящих заголовков. Все имена заголовков записаны в нижнем регистре.
request.setHeader('Foo', 'bar');
request.setHeader('Cookie', ['foo=bar', 'bar=baz']);
const headerNames = request.getHeaderNames();
// headerNames === ['foo', 'cookie'] copy
request.getHeaders()
- Возвращает: <Object>
Возвращает поверхностную копию текущих исходящих заголовков. Поскольку используется поверхностная копия, значения-массивы можно изменять без дополнительных вызовов различных методов модуля http, связанных с заголовками. Ключи возвращаемого объекта — имена заголовков, а значения — соответствующие значения заголовков. Все имена заголовков записаны в нижнем регистре.
Объект, возвращаемый методом request.getHeaders(), не наследует прототип от JavaScript Object. Это означает, что стандартные методы Object, такие как obj.toString(), obj.hasOwnProperty() и другие, не определены и не будут работать.
request.setHeader('Foo', 'bar');
request.setHeader('Cookie', ['foo=bar', 'bar=baz']);
const headers = request.getHeaders();
// headers === { foo: 'bar', 'cookie': ['foo=bar', 'bar=baz'] } copy
request.getRawHeaderNames()
- Возвращает: <string[]>
Возвращает массив, содержащий уникальные имена текущих исходящих исходных заголовков. Имена заголовков возвращаются с исходным регистром, в котором они были заданы.
request.setHeader('Foo', 'bar');
request.setHeader('Set-Cookie', ['foo=bar', 'bar=baz']);
const headerNames = request.getRawHeaderNames();
// headerNames === ['Foo', 'Set-Cookie'] copy
request.hasHeader(name)
Возвращает true, если заголовок, определяемый name, в данный момент задан в исходящих заголовках. Регистр имени заголовка при сравнении не учитывается.
const hasContentType = request.hasHeader('content-type'); copy
request.maxHeadersCount
-
<number> По умолчанию:
2000
Ограничивает максимальное количество заголовков ответа. Если задано значение 0, ограничение не применяется.
request.path
- <string> Путь запроса.
request.method
- <string> Метод запроса.
request.host
- <string> Хост запроса.
request.protocol
- <string> Протокол запроса.
request.removeHeader(name)
-
name<string>
Удаляет заголовок, уже заданный в объекте заголовков.
request.removeHeader('Content-Type'); copy
request.reusedSocket
- <boolean> Указывает, отправляется ли запрос через повторно используемый сокет.
При отправке запроса через агент с включённым keep-alive базовый сокет может быть использован повторно. Однако если сервер закроет соединение в неподходящий момент, клиент может получить ошибку «ECONNRESET».
Модули JavaScript
import http from 'node:http';
// 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 timeoutCommonJS
const http = require('node:http');
// 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Отмечая, использовал запрос сокет повторно или нет, можно реализовать автоматический повтор запроса при ошибке.
Модули JavaScript
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();CommonJS
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();
request.setHeader(name, value)
Задаёт одно значение заголовка в объекте заголовков. Если этот заголовок уже присутствует среди заголовков, которые предстоит отправить, его значение будет заменено. Чтобы отправить несколько заголовков с одинаковым именем, используйте здесь массив строк. Значения, не являющиеся строками, сохраняются без изменений. Поэтому request.getHeader() может возвращать значения нестрокового типа. Однако перед отправкой по сети значения нестрокового типа будут преобразованы в строки.
request.setHeader('Content-Type', 'application/json'); copy или
request.setHeader('Cookie', ['type=ninja', 'language=javascript']); copy Если значение является строкой и содержит символы вне кодировки latin1, будет выброшено исключение.
Если необходимо передать в значении символы UTF-8, закодируйте значение в соответствии со стандартом RFC 8187.
const filename = 'Rock 🎵.txt';
request.setHeader('Content-Disposition', `attachment; filename*=utf-8''${encodeURIComponent(filename)}`); copy
request.setNoDelay([noDelay])
-
noDelay<boolean>
После назначения сокета этому запросу и установки соединения будет вызван socket.setNoDelay().
request.setSocketKeepAlive([enable][, initialDelay])
После назначения сокета этому запросу и установки соединения будет вызван socket.setKeepAlive().
request.setTimeout(timeout[, callback])
-
timeout<number> Время в миллисекундах до истечения времени ожидания запроса. -
callback<Function> Необязательная функция, вызываемая при истечении времени ожидания. То же, что и привязка к событию'timeout'. - Возвращает: <http.ClientRequest>
После назначения сокета этому запросу и установки соединения будет вызван socket.setTimeout().
request.socket
Ссылка на базовый сокет. Обычно пользователям не требуется обращаться к этому свойству. В частности, сокет не будет испускать события 'readable' из-за способа подключения анализатора протокола к сокету.
Модули JavaScript
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
});CommonJS
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
});Гарантируется, что это свойство будет экземпляром класса <net.Socket>, подкласса <stream.Duplex>, если только пользователь не указал тип сокета, отличный от <net.Socket>.
request.uncork()
См. writable.uncork().
request.writableEnded
Равно true после вызова request.end(). Это свойство не указывает, были ли данные сброшены; для этого используйте request.writableFinished.
request.writableFinished
Равно true, если все данные сброшены в базовую систему, непосредственно перед испусканием события 'finish'.
request.write(chunk[, encoding][, callback])
-
chunk<string> | <Buffer> | <Uint8Array> -
encoding<string> -
callback<Function> - Возвращает: <boolean>
Отправляет фрагмент тела. Этот метод можно вызывать несколько раз. Если Content-Length не задан, данные будут автоматически кодироваться с помощью передачи HTTP Chunked, чтобы сервер знал, когда заканчиваются данные. Добавляется заголовок Transfer-Encoding: chunked. Для завершения отправки запроса необходимо вызвать request.end().
Аргумент encoding необязателен и применяется только в том случае, если chunk — строка. Значение по умолчанию: 'utf8'.
Аргумент callback необязателен; он будет вызван при сбросе этого фрагмента данных, но только если фрагмент не пуст.
Возвращает true, если все данные были успешно сброшены в буфер ядра. Возвращает false, если все данные или их часть были помещены в очередь в памяти пользователя. Событие 'drain' будет сгенерировано, когда буфер снова освободится.
При вызове функции write с пустой строкой или буфером она ничего не делает и ожидает новых входных данных.
Класс: http.Server
- Наследует: <net.Server>
Событие: 'checkContinue'
-
request<http.IncomingMessage> -
response<http.ServerResponse>
Событие генерируется при получении каждого запроса с HTTP-Expect: 100-continue. Если это событие не прослушивается, сервер автоматически отправляет соответствующий ответ 100 Continue.
Для обработки этого события нужно вызвать response.writeContinue(), если клиенту следует продолжить отправку тела запроса, либо сформировать соответствующий HTTP-ответ (например, 400 Bad Request), если клиенту не следует продолжать отправку тела запроса.
Если это событие сгенерировано и обработано, событие 'request' не будет сгенерировано.
Событие: 'checkExpectation'
-
request<http.IncomingMessage> -
response<http.ServerResponse>
Событие генерируется при получении каждого запроса с HTTP-заголовком Expect, значение которого не равно 100-continue. Если это событие не прослушивается, сервер автоматически отправляет соответствующий ответ 417 Expectation Failed.
Если это событие сгенерировано и обработано, событие 'request' не будет сгенерировано.
Событие: 'clientError'
-
exception<Error> -
socket<stream.Duplex>
Если для соединения с клиентом генерируется событие 'error', оно будет передано сюда. Прослушиватель этого события отвечает за закрытие или уничтожение базового сокета. Например, может потребоваться более корректно закрыть сокет, отправив пользовательский HTTP-ответ, а не внезапно разрывая соединение. До завершения работы прослушивателя сокет должен быть закрыт или уничтожен.
Гарантируется, что аргументом этого события будет экземпляр класса <net.Socket>, подкласса <stream.Duplex>, если только пользователь не указал тип сокета, отличный от <net.Socket>.
По умолчанию предпринимается попытка закрыть сокет с помощью HTTP-ответа '400 Bad Request' или HTTP-ответа '431 Request Header Fields Too Large' в случае ошибки HPE_HEADER_OVERFLOW. Если сокет недоступен для записи или заголовки текущего связанного объекта http.ServerResponse уже отправлены, сокет немедленно уничтожается.
socket — это объект net.Socket, в котором возникла ошибка.
Модули JavaScript
import http from 'node:http';
const server = http.createServer((req, res) => {
res.end();
});
server.on('clientError', (err, socket) => {
socket.end('HTTP/1.1 400 Bad Request\r\n\r\n');
});
server.listen(8000);CommonJS
const http = require('node:http');
const server = http.createServer((req, res) => {
res.end();
});
server.on('clientError', (err, socket) => {
socket.end('HTTP/1.1 400 Bad Request\r\n\r\n');
});
server.listen(8000);При возникновении события 'clientError' объекты request и response отсутствуют, поэтому любой HTTP-ответ, включая заголовки ответа и полезную нагрузку, должен записываться непосредственно в объект socket. Необходимо убедиться, что ответ является правильно сформированным сообщением HTTP-ответа.
err — это экземпляр Error с двумя дополнительными полями:
-
bytesParsed: количество байтов пакета запроса, которые Node.js, возможно, удалось корректно разобрать; -
rawPacket: необработанный пакет текущего запроса.
В некоторых случаях клиент уже получил ответ и/или сокет уже уничтожен, например, при ошибках ECONNRESET. Перед отправкой данных в сокет лучше проверить, доступен ли он для записи.
server.on('clientError', (err, socket) => {
if (err.code === 'ECONNRESET' || !socket.writable) {
return;
}
socket.end('HTTP/1.1 400 Bad Request\r\n\r\n');
}); copy Событие: 'close'
Событие генерируется при закрытии сервера.
Событие: 'connect'
-
request<http.IncomingMessage> Аргументы HTTP-запроса, такие же, как в событии'request' -
socket<stream.Duplex> Сетевой сокет между сервером и клиентом -
head<Buffer> Первый пакет туннельного потока (может быть пустым)
Событие генерируется при каждом запросе клиента на использование метода HTTP CONNECT. Если это событие не прослушивается, соединения клиентов, запрашивающих метод CONNECT, будут закрыты.
Гарантируется, что аргументом этого события будет экземпляр класса <net.Socket>, подкласса <stream.Duplex>, если только пользователь не указал тип сокета, отличный от <net.Socket>.
После генерации этого события у сокета запроса не будет прослушивателя события 'data', поэтому для обработки данных, отправляемых серверу через этот сокет, необходимо привязать такой прослушиватель.
Событие: 'connection'
-
socket<stream.Duplex>
Это событие генерируется при установлении нового потока TCP. Обычно socket — это объект типа net.Socket. Обычно пользователям не требуется обращаться к этому событию. В частности, сокет не будет генерировать события 'readable' из-за того, как анализатор протокола подключается к сокету. Доступ к socket также можно получить через request.socket.
Пользователи также могут явно генерировать это событие, чтобы передавать соединения HTTP-серверу. В этом случае можно передать любой поток Duplex.
Если здесь вызвана функция socket.setTimeout(), тайм-аут будет заменен на server.keepAliveTimeout после обработки сокетом запроса (если server.keepAliveTimeout не равен нулю).
Гарантируется, что аргументом этого события будет экземпляр класса <net.Socket>, подкласса <stream.Duplex>, если только пользователь не указал тип сокета, отличный от <net.Socket>.
Событие: 'dropRequest'
-
request<http.IncomingMessage> Аргументы HTTP-запроса, такие же, как в событии'request' -
socket<stream.Duplex> Сетевой сокет между сервером и клиентом
Когда количество запросов через сокет достигает порогового значения server.maxRequestsPerSocket, сервер будет отбрасывать новые запросы, вместо этого генерируя событие 'dropRequest', а затем отправит клиенту 503.
Событие: 'request'
-
request<http.IncomingMessage> -
response<http.ServerResponse>
Событие генерируется при каждом запросе. Через одно соединение может поступать несколько запросов (в случае соединений HTTP Keep-Alive).
Событие: 'upgrade'
-
request<http.IncomingMessage> Аргументы HTTP-запроса, такие же, как в событии'request' -
socket<stream.Duplex> Сетевой сокет между сервером и клиентом -
head<Buffer> Первый пакет обновленного потока (может быть пустым)
Событие генерируется при каждом запросе клиента на обновление HTTP-соединения. Прослушивать это событие необязательно, и клиенты не могут настаивать на смене протокола.
После генерации этого события у сокета запроса не будет прослушивателя события 'data', поэтому для обработки данных, отправляемых серверу через этот сокет, необходимо привязать такой прослушиватель.
Гарантируется, что аргументом этого события будет экземпляр класса <net.Socket>, подкласса <stream.Duplex>, если только пользователь не указал тип сокета, отличный от <net.Socket>.
server.close([callback])
-
callback<Function>
Прекращает прием новых соединений сервером и закрывает все соединения с этим сервером, по которым не отправляется запрос и для которых не ожидается ответ. См. net.Server.close().
const http = require('node:http');
const server = http.createServer({ keepAliveTimeout: 60000 }, (req, res) => {
res.writeHead(200, { 'Content-Type': 'application/json' });
res.end(JSON.stringify({
data: 'Hello World!',
}));
});
server.listen(8000);
// Close the server after 10 seconds
setTimeout(() => {
server.close(() => {
console.log('server on port 8000 closed successfully');
});
}, 10000); copy
server.closeAllConnections()
Закрывает все установленные HTTP(S)-соединения с этим сервером, включая активные соединения, по которым отправляется запрос или ожидается ответ. При этом не уничтожаются сокеты, переключенные на другой протокол, например WebSocket или HTTP/2.
Это принудительный способ закрытия всех соединений, поэтому его следует использовать с осторожностью. При использовании этого метода вместе с
server.closeрекомендуется вызывать его послеserver.close, чтобы избежать гонок, при которых новые соединения создаются между вызовами этого метода иserver.close.
const http = require('node:http');
const server = http.createServer({ keepAliveTimeout: 60000 }, (req, res) => {
res.writeHead(200, { 'Content-Type': 'application/json' });
res.end(JSON.stringify({
data: 'Hello World!',
}));
});
server.listen(8000);
// Close the server after 10 seconds
setTimeout(() => {
server.close(() => {
console.log('server on port 8000 closed successfully');
});
// Closes all connections, ensuring the server closes successfully
server.closeAllConnections();
}, 10000); copy
server.closeIdleConnections()
Закрывает все соединения с этим сервером, по которым не отправляется запрос и для которых не ожидается ответ.
Начиная с Node.js 19.0.0, для закрытия
keep-aliveсоединений вместе сserver.closeвызывать этот метод не требуется. Его использование не причинит вреда и может быть полезно для обеспечения обратной совместимости библиотек и приложений, которым необходимо поддерживать версии до 19.0.0. При использовании этого метода вместе сserver.closeрекомендуется вызывать его послеserver.close, чтобы избежать гонок, при которых новые соединения создаются между вызовами этого метода иserver.close.
const http = require('node:http');
const server = http.createServer({ keepAliveTimeout: 60000 }, (req, res) => {
res.writeHead(200, { 'Content-Type': 'application/json' });
res.end(JSON.stringify({
data: 'Hello World!',
}));
});
server.listen(8000);
// Close the server after 10 seconds
setTimeout(() => {
server.close(() => {
console.log('server on port 8000 closed successfully');
});
// Closes idle connections, such as keep-alive connections. Server will close
// once remaining active connections are terminated
server.closeIdleConnections();
}, 10000); copy
server.headersTimeout
-
<number> По умолчанию: меньшее из значений
server.requestTimeoutи60000.
Ограничивает время ожидания анализатором получения полных HTTP-заголовков.
По истечении времени ожидания сервер отправляет ответ со статусом 408, не передавая запрос прослушивателю запросов, а затем закрывает соединение.
Для защиты от потенциальных атак типа «отказ в обслуживании» это значение должно быть ненулевым (например, 120 секунд), если сервер развернут без обратного прокси-сервера.
server.listen()
Запускает HTTP-сервер и начинает прослушивать соединения. Этот метод идентичен методу server.listen() класса net.Server.
server.listening
- <boolean> Указывает, прослушивает ли сервер соединения.
server.maxHeadersCount
-
<number> По умолчанию:
2000
Ограничивает максимальное количество входящих заголовков. Если установить значение 0, ограничение применяться не будет.
server.requestTimeout
-
<number> По умолчанию:
300000
Задает время ожидания в миллисекундах для получения всего запроса от клиента.
По истечении времени ожидания сервер отправляет ответ со статусом 408, не передавая запрос прослушивателю запросов, а затем закрывает соединение.
Для защиты от потенциальных атак типа «отказ в обслуживании» это значение должно быть ненулевым (например, 120 секунд), если сервер развернут без обратного прокси-сервера.
server.setTimeout([msecs][, callback])
-
msecs<number> По умолчанию: 0 (без тайм-аута) -
callback<Function> - Возвращает: <http.Server>
Задает время ожидания для сокетов и при его истечении генерирует событие 'timeout' для объекта Server, передавая сокет в качестве аргумента.
Если для объекта Server установлен прослушиватель события 'timeout', ему будет передан сокет, для которого истекло время ожидания.
По умолчанию время ожидания для сокетов Server не ограничено. Однако если для события 'timeout' объекта Server назначена функция обратного вызова, обработку тайм-аутов необходимо реализовать явно.
server.maxRequestsPerSocket
- <number> Количество запросов на сокет. По умолчанию: 0 (без ограничений)
Максимальное количество запросов, которое может обработать сокет до закрытия постоянного соединения.
Значение 0 отключает ограничение.
При достижении ограничения значение заголовка Connection будет установлено в close, однако соединение фактически не закроется; последующие запросы, отправленные после достижения ограничения, получат в ответ 503 Service Unavailable.
server.timeout
- <number> Время ожидания в миллисекундах. По умолчанию: 0 (без тайм-аута)
Количество миллисекунд бездействия, по истечении которого сокет считается неактивным.
Значение 0 отключает действие тайм-аута для входящих соединений.
Логика тайм-аута сокета настраивается при подключении, поэтому изменение этого значения влияет только на новые соединения с сервером, но не на уже существующие.
server.keepAliveTimeout
-
<number> Время ожидания в миллисекундах. По умолчанию:
5000(5 секунд).
Количество миллисекунд бездействия, которое сервер должен ждать поступления дополнительных данных после отправки последнего ответа, прежде чем сокет будет уничтожен. Если до истечения времени ожидания keep-alive сервер получает новые данные, обычный тайм-аут бездействия сбрасывается, то есть server.timeout.
Значение 0 отключает действие тайм-аута keep-alive для входящих соединений. При значении 0 HTTP-сервер ведет себя так же, как в версиях Node.js до 8.0.0, в которых тайм-аута keep-alive не было.
Логика тайм-аута сокета настраивается при подключении, поэтому изменение этого значения влияет только на новые соединения с сервером, но не на уже существующие.
server[Symbol.asyncDispose]()
Вызывает server.close() и возвращает промис, который выполняется после закрытия сервера.
Class: http.ServerResponse
- Наследует: <http.OutgoingMessage>
Этот объект создаётся внутренними средствами HTTP-сервера, а не пользователем. Он передаётся в качестве второго параметра событию 'request'.
Event: 'close'
Указывает, что ответ завершён или его базовое соединение было преждевременно прервано (до завершения ответа).
Event: 'finish'
Вызывается, когда ответ отправлен. Точнее, это событие вызывается, когда последний сегмент заголовков и тела ответа передан операционной системе для отправки по сети. Это не означает, что клиент уже что-либо получил.
response.addTrailers(headers)
-
headers<Object>
Этот метод добавляет к ответу завершающие HTTP-заголовки (заголовок в конце сообщения).
Завершающие заголовки будут отправлены только при использовании для ответа блочного кодирования; в противном случае (например, если запрос был HTTP/1.0) они будут молча отброшены.
Для отправки завершающих заголовков протокол HTTP требует отправить заголовок Trailer со списком имён полей заголовков в его значении. Например:
response.writeHead(200, { 'Content-Type': 'text/plain',
'Trailer': 'Content-MD5' });
response.write(fileData);
response.addTrailers({ 'Content-MD5': '7895bf4b8828b55ceaf47747b4bca667' });
response.end(); copy Попытка задать имя или значение поля заголовка, содержащие недопустимые символы, приведёт к выбрасыванию TypeError.
response.connection
response.socket.См. response.socket.
response.cork()
См. writable.cork().
response.end([data[, encoding]][, callback])
-
data<string> | <Buffer> | <Uint8Array> -
encoding<string> -
callback<Function> - Возвращает: <this>
Этот метод сообщает серверу, что все заголовки и тело ответа отправлены; сервер должен считать это сообщение завершённым. Метод response.end() ДОЛЖЕН вызываться для каждого ответа.
Если указан data, эффект будет аналогичен вызову response.write(data, encoding), за которым следует response.end(callback).
Если указан callback, он будет вызван после завершения потока ответа.
response.finished
response.writableEnded.Свойство response.finished будет иметь значение true, если был вызван response.end().
response.flushHeaders()
Отправляет заголовки ответа. См. также: request.flushHeaders().
response.getHeader(name)
Возвращает заголовок, который уже добавлен в очередь, но ещё не отправлен клиенту. Регистр букв в имени не учитывается. Тип возвращаемого значения зависит от аргументов, переданных в response.setHeader().
response.setHeader('Content-Type', 'text/html');
response.setHeader('Content-Length', Buffer.byteLength(body));
response.setHeader('Set-Cookie', ['type=ninja', 'language=javascript']);
const contentType = response.getHeader('content-type');
// contentType is 'text/html'
const contentLength = response.getHeader('Content-Length');
// contentLength is of type number
const setCookie = response.getHeader('set-cookie');
// setCookie is of type string[] copy
response.getHeaderNames()
- Возвращает: <string[]>
Возвращает массив с уникальными именами текущих исходящих заголовков. Все имена заголовков записаны строчными буквами.
response.setHeader('Foo', 'bar');
response.setHeader('Set-Cookie', ['foo=bar', 'bar=baz']);
const headerNames = response.getHeaderNames();
// headerNames === ['foo', 'set-cookie'] copy
response.getHeaders()
- Возвращает: <Object>
Возвращает неглубокую копию текущих исходящих заголовков. Поскольку используется неглубокая копия, значения-массивы можно изменять без дополнительных вызовов различных методов модуля http, связанных с заголовками. Ключи возвращаемого объекта — имена заголовков, а значения — соответствующие значения заголовков. Все имена заголовков записаны строчными буквами.
Объект, возвращаемый методом response.getHeaders(), не наследует прототип от JavaScript-объекта Object. Это означает, что стандартные методы Object, такие как obj.toString(), obj.hasOwnProperty() и другие, не определены и не будут работать.
response.setHeader('Foo', 'bar');
response.setHeader('Set-Cookie', ['foo=bar', 'bar=baz']);
const headers = response.getHeaders();
// headers === { foo: 'bar', 'set-cookie': ['foo=bar', 'bar=baz'] } copy
response.hasHeader(name)
Возвращает true, если заголовок с именем name в данный момент установлен среди исходящих заголовков. Регистр букв в имени заголовка не учитывается.
const hasContentType = response.hasHeader('content-type'); copy
response.headersSent
Логическое значение (только для чтения). True, если заголовки были отправлены, и false в противном случае.
response.removeHeader(name)
-
name<string>
Удаляет заголовок, поставленный в очередь для неявной отправки.
response.removeHeader('Content-Encoding'); copy
response.req
Ссылка на исходный объект HTTP request.
response.sendDate
Если значение равно true, заголовок Date будет автоматически сформирован и отправлен в ответе, если его ещё нет среди заголовков. По умолчанию — true.
Отключать эту функцию следует только для тестирования; протокол HTTP требует наличия заголовка Date в ответах.
response.setHeader(name, value)
-
name<string> -
value<any> - Возвращает: <http.ServerResponse>
Возвращает объект ответа.
Задаёт одно значение заголовка для неявных заголовков. Если такой заголовок уже есть среди заголовков, предназначенных для отправки, его значение будет заменено. Чтобы отправить несколько заголовков с одинаковым именем, используйте массив строк. Значения, не являющиеся строками, сохраняются без изменений. Поэтому response.getHeader() может возвращать значения, не являющиеся строками. Однако перед отправкой по сети такие значения будут преобразованы в строки. Вызывающей стороне возвращается тот же объект ответа, что позволяет объединять вызовы в цепочку.
response.setHeader('Content-Type', 'text/html'); copy или
response.setHeader('Set-Cookie', ['type=ninja', 'language=javascript']); copy Попытка задать имя или значение поля заголовка, содержащие недопустимые символы, приведёт к выбрасыванию TypeError.
Заголовки, заданные с помощью response.setHeader(), объединяются с заголовками, переданными в response.writeHead(); приоритет имеют заголовки, переданные в response.writeHead().
// Returns content-type = text/plain
const server = http.createServer((req, res) => {
res.setHeader('Content-Type', 'text/html');
res.setHeader('X-Foo', 'bar');
res.writeHead(200, { 'Content-Type': 'text/plain' });
res.end('ok');
}); copy Если вызван метод response.writeHead(), а этот метод не вызывался, переданные значения заголовков будут напрямую записаны в сетевой канал без внутреннего кэширования, и response.getHeader() для заголовка не вернёт ожидаемый результат. Если требуется постепенно добавлять заголовки с возможностью их последующего получения и изменения, используйте response.setHeader() вместо response.writeHead().
response.setTimeout(msecs[, callback])
-
msecs<number> -
callback<Function> - Возвращает: <http.ServerResponse>
Устанавливает для Socket значение тайм-аута msecs. Если передан callback, он добавляется как обработчик события 'timeout' объекта ответа.
Если для запроса, ответа или сервера не добавлен обработчик события 'timeout', сокеты уничтожаются по истечении времени ожидания. Если для событий 'timeout' запроса, ответа или сервера назначен обработчик, сокеты, время ожидания которых истекло, необходимо обрабатывать явно.
response.socket
Ссылка на базовый сокет. Обычно пользователям не требуется обращаться к этому свойству. В частности, сокет не будет генерировать события 'readable' из-за того, как анализатор протокола подключается к сокету. После response.end() значение свойства становится null.
Модули JavaScript
import http from 'node:http';
const server = http.createServer((req, res) => {
const ip = res.socket.remoteAddress;
const port = res.socket.remotePort;
res.end(`Your IP address is ${ip} and your source port is ${port}.`);
}).listen(3000);CommonJS
const http = require('node:http');
const server = http.createServer((req, res) => {
const ip = res.socket.remoteAddress;
const port = res.socket.remotePort;
res.end(`Your IP address is ${ip} and your source port is ${port}.`);
}).listen(3000);Гарантируется, что это свойство содержит экземпляр класса <net.Socket>, подкласса <stream.Duplex>, если только пользователь не указал тип сокета, отличный от <net.Socket>.
response.statusCode
-
<number> По умолчанию:
200
При использовании неявных заголовков (без явного вызова response.writeHead()) это свойство задаёт код состояния, который будет отправлен клиенту при отправке заголовков.
response.statusCode = 404; copy
После отправки заголовка ответа клиенту это свойство содержит отправленный код состояния.
response.statusMessage
При использовании неявных заголовков (без явного вызова response.writeHead()) это свойство задаёт сообщение о состоянии, которое будет отправлено клиенту при отправке заголовков. Если оставить значение undefined, будет использоваться стандартное сообщение для соответствующего кода состояния.
response.statusMessage = 'Not found'; copy
После отправки заголовка ответа клиенту это свойство содержит отправленное сообщение о состоянии.
response.strictContentLength
-
<boolean> По умолчанию:
false
Если установлено значение true, Node.js проверит, совпадает ли значение заголовка Content-Length с размером тела в байтах. Несоответствие значению заголовка Content-Length приведёт к выбрасыванию Error с кодом code: 'ERR_HTTP_CONTENT_LENGTH_MISMATCH'.
response.uncork()
См. writable.uncork().
response.writableEnded
Имеет значение true после вызова response.end(). Это свойство не указывает, были ли данные отправлены; для этого используйте response.writableFinished.
response.writableFinished
Имеет значение true, если все данные отправлены в базовую систему, непосредственно перед вызовом события 'finish'.
response.write(chunk[, encoding][, callback])
-
chunk<string> | <Buffer> | <Uint8Array> -
encoding<string> По умолчанию:'utf8' -
callback<Function> - Возвращает: <boolean>
Если вызвать этот метод до вызова response.writeHead(), он переключится в режим неявных заголовков и отправит их.
Отправляет фрагмент тела ответа. Этот метод можно вызывать несколько раз, чтобы передать последовательные части тела.
Если для createServer установлено значение true, rejectNonStandardBodyWrites, запись в тело не допускается, когда метод запроса или состояние ответа не поддерживают содержимое. При попытке записать данные в тело HEAD-запроса или ответа с кодом 204 либо 304 синхронно выбрасывается Error с кодом ERR_HTTP_BODY_NOT_ALLOWED.
chunk может быть строкой или буфером. Если chunk — строка, второй параметр задаёт способ её кодирования в поток байтов. callback будет вызван после отправки этого фрагмента данных.
Это необработанное тело HTTP, не имеющее отношения к кодированию составного тела более высокого уровня, которое может использоваться.
При первом вызове response.write() клиенту будут отправлены буферизованные заголовки и первый фрагмент тела. При втором вызове response.write() Node.js предполагает, что данные будут передаваться потоком, и отправляет новые данные отдельно. То есть ответ буферизуется до первого фрагмента тела.
Возвращает true, если все данные успешно отправлены в буфер ядра. Возвращает false, если все данные или их часть поставлены в очередь в пользовательской памяти. Событие 'drain' будет вызвано, когда буфер снова освободится.
response.writeContinue()
Отправляет клиенту сообщение HTTP/1.1 100 Continue, указывающее, что следует отправить тело запроса. См. событие 'checkContinue' объекта Server.
response.writeEarlyHints(hints[, callback])
-
hints<Object> -
callback<Function>
Отправляет клиенту сообщение HTTP/1.1 103 Early Hints с заголовком Link, указывающим, что пользовательский агент может предварительно загрузить связанные ресурсы или установить с ними предварительное соединение. hints — объект, содержащий значения заголовков, которые будут отправлены вместе с сообщением ранних подсказок. Необязательный аргумент callback будет вызван после записи сообщения ответа.
Пример
const earlyHintsLink = '</styles.css>; rel=preload; as=style';
response.writeEarlyHints({
'link': earlyHintsLink,
});
const earlyHintsLinks = [
'</styles.css>; rel=preload; as=style',
'</scripts.js>; rel=preload; as=script',
];
response.writeEarlyHints({
'link': earlyHintsLinks,
'x-trace-id': 'id for diagnostics',
});
const earlyHintsCallback = () => console.log('early hints message sent');
response.writeEarlyHints({
'link': earlyHintsLinks,
}, earlyHintsCallback); copy
response.writeHead(statusCode[, statusMessage][, headers])
-
statusCode<number> -
statusMessage<string> -
headers<Object> | <Array> - Возвращает: <http.ServerResponse>
Отправляет заголовок ответа на запрос. Код состояния — это трёхзначный код состояния HTTP, например 404. Последний аргумент, headers, — это заголовки ответа. В качестве второго аргумента можно дополнительно передать понятное человеку statusMessage.
headers может быть Array, в котором ключи и значения представлены в одном списке. Это не список кортежей. Таким образом, элементы с чётными индексами являются ключами, а элементы с нечётными индексами — соответствующими значениями. Массив имеет тот же формат, что и request.rawHeaders.
Возвращает ссылку на ServerResponse, что позволяет объединять вызовы в цепочку.
const body = 'hello world';
response
.writeHead(200, {
'Content-Length': Buffer.byteLength(body),
'Content-Type': 'text/plain',
})
.end(body); copy Этот метод можно вызвать только один раз для сообщения и только до вызова response.end().
Если до этого вызвать response.write() или response.end(), будут вычислены неявные/изменяемые заголовки и вызвана эта функция.
Заголовки, заданные с помощью response.setHeader(), объединяются с заголовками, переданными в response.writeHead(); приоритет имеют заголовки, переданные в response.writeHead().
Если вызвать этот метод, не вызывая response.setHeader(), переданные значения заголовков будут напрямую записаны в сетевой канал без внутреннего кэширования, и response.getHeader() для заголовка не вернёт ожидаемый результат. Если требуется постепенно добавлять заголовки с возможностью их последующего получения и изменения, используйте вместо этого response.setHeader().
// Returns content-type = text/plain
const server = http.createServer((req, res) => {
res.setHeader('Content-Type', 'text/html');
res.setHeader('X-Foo', 'bar');
res.writeHead(200, { 'Content-Type': 'text/plain' });
res.end('ok');
}); copy Content-Length измеряется в байтах, а не в символах. Используйте Buffer.byteLength(), чтобы определить длину тела в байтах. Node.js проверит, совпадают ли Content-Length и длина переданного тела.
Попытка задать имя или значение поля заголовка, содержащие недопустимые символы, приведёт к выбрасыванию [Error][].
response.writeProcessing()
Отправляет клиенту сообщение HTTP/1.1 102 Processing, указывающее, что следует отправить тело запроса.
Class: http.IncomingMessage
- Расширяет: <stream.Readable>
Объект IncomingMessage создаётся с помощью http.Server или http.ClientRequest и передаётся в качестве первого аргумента соответственно событиям 'request' и 'response'. Его можно использовать для доступа к статусу ответа, заголовкам и данным.
В отличие от значения socket, являющегося подклассом <stream.Duplex>, сам IncomingMessage расширяет <stream.Readable> и создаётся отдельно для разбора и отправки входящих заголовков и полезной нагрузки HTTP, поскольку базовый сокет может использоваться повторно несколько раз при keep-alive.
Event: 'aborted'
'close'.Вызывается, когда запрос прерван.
Event: 'close'
Вызывается после завершения запроса.
message.aborted
Свойство message.aborted будет иметь значение true, если запрос был прерван.
message.complete
Свойство message.complete будет иметь значение true, если полное HTTP-сообщение было получено и успешно разобрано.
Это свойство особенно полезно для определения того, полностью ли клиент или сервер передал сообщение до завершения соединения:
const req = http.request({
host: '127.0.0.1',
port: 8080,
method: 'POST',
}, (res) => {
res.resume();
res.on('end', () => {
if (!res.complete)
console.error(
'The connection was terminated while the message was still being sent');
});
}); copy
message.connection
message.socket.Псевдоним для message.socket.
message.destroy([error])
Вызывает destroy() для сокета, получившего IncomingMessage. Если указан error, в сокете вызывается событие 'error', а error передаётся в качестве аргумента всем его обработчикам.
message.headers
Объект заголовков запроса/ответа.
Пары «ключ-значение» заголовков. Имена заголовков приводятся к нижнему регистру.
// Prints something like:
//
// { 'user-agent': 'curl/7.22.0',
// host: '127.0.0.1:8000',
// accept: '*/*' }
console.log(request.headers); copy Дубликаты в необработанных заголовках обрабатываются следующим образом в зависимости от имени заголовка:
- Дубликаты
age,authorization,content-length,content-type,etag,expires,from,host,if-modified-since,if-unmodified-since,last-modified,location,max-forwards,proxy-authorization,referer,retry-after,serverилиuser-agentотбрасываются. Чтобы объединить повторяющиеся значения перечисленных выше заголовков, используйте параметрjoinDuplicateHeadersвhttp.request()иhttp.createServer(). Дополнительные сведения см. в разделе 5.3 RFC 9110. -
set-cookieвсегда является массивом. Дубликаты добавляются в массив. - Значения дублирующихся заголовков
cookieобъединяются с помощью;. - Значения всех остальных заголовков объединяются с помощью
,.
message.headersDistinct
Похоже на message.headers, но без логики объединения: значения всегда являются массивами строк, даже если заголовок получен только один раз.
// Prints something like:
//
// { 'user-agent': ['curl/7.22.0'],
// host: ['127.0.0.1:8000'],
// accept: ['*/*'] }
console.log(request.headersDistinct); copy
message.httpVersion
Для запроса на сервере — версия HTTP, отправленная клиентом. Для ответа клиенту — версия HTTP сервера, с которым установлено соединение. Вероятно, это '1.1' или '1.0'.
Кроме того, message.httpVersionMajor — это первое целое число, а message.httpVersionMinor — второе.
message.method
Действительно только для запроса, полученного от http.Server.
Метод запроса в виде строки. Только для чтения. Примеры: 'GET', 'DELETE'.
message.rawHeaders
Список необработанных заголовков запроса/ответа точно в том виде, в котором они были получены.
Ключи и значения находятся в одном списке. Это не список кортежей. Поэтому элементы с чётными индексами являются ключами, а элементы с нечётными индексами — соответствующими значениями.
Имена заголовков не приводятся к нижнему регистру, а дубликаты не объединяются.
// Prints something like: // // [ 'user-agent', // 'this is invalid because there can be only one', // 'User-Agent', // 'curl/7.22.0', // 'Host', // '127.0.0.1:8000', // 'ACCEPT', // '*/*' ] console.log(request.rawHeaders); copy
message.rawTrailers
Ключи и значения необработанных трейлеров запроса/ответа точно в том виде, в котором они были получены. Заполняется только при событии 'end'.
message.setTimeout(msecs[, callback])
-
msecs<number> -
callback<Function> - Возвращает: <http.IncomingMessage>
Вызывает message.socket.setTimeout(msecs, callback).
message.socket
Объект net.Socket, связанный с соединением.
При использовании HTTPS вызовите request.socket.getPeerCertificate(), чтобы получить сведения об аутентификации клиента.
Это свойство гарантированно является экземпляром класса <net.Socket>, подкласса <stream.Duplex>, если только пользователь не указал тип сокета, отличный от <net.Socket>, или значение не было обнулено внутренним образом.
message.statusCode
Действительно только для ответа, полученного от http.ClientRequest.
Трёхзначный код состояния HTTP-ответа. Например, 404.
message.statusMessage
Действительно только для ответа, полученного от http.ClientRequest.
Текст статуса HTTP-ответа (фраза причины). Например, OK или Internal Server Error.
message.trailers
Объект трейлеров запроса/ответа. Заполняется только при событии 'end'.
message.trailersDistinct
Похоже на message.trailers, но без логики объединения: значения всегда являются массивами строк, даже если заголовок получен только один раз. Заполняется только при событии 'end'.
message.url
Действительно только для запроса, полученного от http.Server.
Строка URL запроса. Она содержит только URL, присутствующий в фактическом HTTP-запросе. Рассмотрим следующий запрос:
GET /status?name=ryan HTTP/1.1 Accept: text/plain copy
Чтобы разобрать URL на составляющие:
new URL(`http://${process.env.HOST ?? 'localhost'}${request.url}`); copy Если request.url имеет значение '/status?name=ryan', а process.env.HOST не определён:
$ node
> new URL(`http://${process.env.HOST ?? 'localhost'}${request.url}`);
URL {
href: 'http://localhost/status?name=ryan',
origin: 'http://localhost',
protocol: 'http:',
username: '',
password: '',
host: 'localhost',
hostname: 'localhost',
port: '',
pathname: '/status',
search: '?name=ryan',
searchParams: URLSearchParams { 'name' => 'ryan' },
hash: ''
} copy Убедитесь, что для process.env.HOST задано имя хоста сервера, либо рассмотрите возможность полной замены этой части. При использовании req.headers.host обязательно выполняйте надлежащую проверку, поскольку клиенты могут указать собственный заголовок Host.
Класс: http.OutgoingMessage
- Расширяет: <Stream>
Этот класс является родительским классом для http.ClientRequest и http.ServerResponse. С точки зрения участников HTTP-транзакции это абстрактное исходящее сообщение.
Событие: 'drain'
Возникает, когда буфер сообщения снова освобождается.
Событие: 'finish'
Возникает после успешного завершения передачи.
Событие: 'prefinish'
Возникает после вызова outgoingMessage.end(). К моменту возникновения события все данные обработаны, но не обязательно полностью переданы.
outgoingMessage.addTrailers(headers)
-
headers<Object>
Добавляет к сообщению завершающие заголовки HTTP (заголовки в конце сообщения).
Завершающие заголовки будут отправлены только при передаче сообщения с кодированием частями. В противном случае они будут без предупреждения отброшены.
Для отправки завершающих заголовков HTTP требуется передать заголовок Trailer со списком имен полей заголовков в качестве значения, например:
message.writeHead(200, { 'Content-Type': 'text/plain',
'Trailer': 'Content-MD5' });
message.write(fileData);
message.addTrailers({ 'Content-MD5': '7895bf4b8828b55ceaf47747b4bca667' });
message.end(); copy Попытка задать имя поля заголовка или его значение, содержащие недопустимые символы, приведет к выбросу TypeError.
outgoingMessage.appendHeader(name, value)
-
name<string> Имя заголовка -
value<string> | <string[]> Значение заголовка - Возвращает: <this>
Добавляет одно значение заголовка в объект заголовков.
Если значение является массивом, это равносильно многократному вызову данного метода.
Если у заголовка не было предыдущих значений, это равносильно вызову outgoingMessage.setHeader(name, value).
В зависимости от значения options.uniqueHeaders на момент создания клиентского запроса или сервера заголовок будет отправлен несколько раз либо один раз со значениями, объединенными с помощью ; .
outgoingMessage.connection
outgoingMessage.socket.Псевдоним outgoingMessage.socket.
outgoingMessage.cork()
См. writable.cork().
outgoingMessage.destroy([error])
Уничтожает сообщение. Если с сообщением связан сокет и он подключен, этот сокет также будет уничтожен.
outgoingMessage.end(chunk[, encoding][, callback])
-
chunk<string> | <Buffer> | <Uint8Array> -
encoding<string> Необязательный, по умолчанию:utf8 -
callback<Function> Необязательный - Возвращает: <this>
Завершает исходящее сообщение. Если какие-либо части тела сообщения еще не отправлены, они будут переданы в нижележащую систему. Если сообщение передается частями, будет отправлена завершающая часть 0\r\n\r\n, а также завершающие заголовки (если они есть).
Если указан chunk, это равносильно вызову outgoingMessage.write(chunk, encoding), за которым следует outgoingMessage.end(callback).
Если задан callback, он будет вызван после завершения сообщения (эквивалентно обработчику события 'finish').
outgoingMessage.flushHeaders()
Сбрасывает заголовки сообщения.
Для повышения эффективности Node.js обычно буферизует заголовки сообщения до вызова outgoingMessage.end() или записи первого фрагмента данных сообщения. Затем программа пытается упаковать заголовки и данные в один TCP-пакет.
Обычно это желательно (экономится один обмен данными по TCP), однако не в тех случаях, когда первые данные отправляются значительно позже. outgoingMessage.flushHeaders() обходит эту оптимизацию и запускает передачу сообщения.
outgoingMessage.getHeader(name)
-
name<string> Имя заголовка - Возвращает: <string> | <undefined>
Получает значение HTTP-заголовка с указанным именем. Если такой заголовок не задан, возвращаемым значением будет undefined.
outgoingMessage.getHeaderNames()
- Возвращает: <string[]>
Возвращает массив с уникальными именами текущих исходящих заголовков. Все имена записаны в нижнем регистре.
outgoingMessage.getHeaders()
- Возвращает: <Object>
Возвращает поверхностную копию текущих исходящих заголовков. Поскольку используется поверхностная копия, значения-массивы можно изменять без дополнительных вызовов различных методов модуля HTTP, связанных с заголовками. Ключи возвращаемого объекта — имена заголовков, а значения — соответствующие значения заголовков. Все имена заголовков записаны в нижнем регистре.
Объект, возвращаемый методом outgoingMessage.getHeaders(), не наследует прототип от JavaScript-объекта Object. Это означает, что стандартные методы Object, такие как obj.toString(), obj.hasOwnProperty() и другие, не определены и работать не будут.
outgoingMessage.setHeader('Foo', 'bar');
outgoingMessage.setHeader('Set-Cookie', ['foo=bar', 'bar=baz']);
const headers = outgoingMessage.getHeaders();
// headers === { foo: 'bar', 'set-cookie': ['foo=bar', 'bar=baz'] } copy
outgoingMessage.hasHeader(name)
Возвращает true, если заголовок с именем name задан в исходящих заголовках. Регистр букв в имени заголовка не учитывается.
const hasContentType = outgoingMessage.hasHeader('content-type'); copy
outgoingMessage.headersSent
Только для чтения. Значение true, если заголовки отправлены, иначе false.
outgoingMessage.pipe()
Переопределяет метод stream.pipe(), унаследованный от устаревшего класса Stream, который является родительским классом http.OutgoingMessage.
Вызов этого метода приведет к выбросу Error, поскольку outgoingMessage — это поток, доступный только для записи.
outgoingMessage.removeHeader(name)
-
name<string> Имя заголовка
Удаляет заголовок, поставленный в очередь для неявной отправки.
outgoingMessage.removeHeader('Content-Encoding'); copy
outgoingMessage.setHeader(name, value)
Задает одно значение заголовка. Если заголовок уже присутствует среди заголовков, которые предстоит отправить, его значение будет заменено. Чтобы отправить несколько заголовков с одинаковым именем, используйте массив строк.
outgoingMessage.setHeaders(headers)
Задает несколько значений заголовков для неявных заголовков. headers должен быть экземпляром Headers или Map; если заголовок уже присутствует среди заголовков, которые предстоит отправить, его значение будет заменено.
const headers = new Headers({ foo: 'bar' });
outgoingMessage.setHeaders(headers); copy или
const headers = new Map([['foo', 'bar']]); outgoingMessage.setHeaders(headers); copy
Если заголовки заданы с помощью outgoingMessage.setHeaders(), они объединяются с заголовками, переданными в response.writeHead(); при этом приоритет имеют заголовки, переданные в response.writeHead().
// Returns content-type = text/plain
const server = http.createServer((req, res) => {
const headers = new Headers({ 'Content-Type': 'text/html' });
res.setHeaders(headers);
res.writeHead(200, { 'Content-Type': 'text/plain' });
res.end('ok');
}); copy
outgoingMessage.setTimeout(msesc[, callback])
-
msesc<number> -
callback<Function> Необязательная функция, вызываемая при истечении времени ожидания. То же, что привязка к событиюtimeout. - Возвращает: <this>
После связывания сообщения с сокетом и подключения сокета будет вызван socket.setTimeout(), которому в качестве первого параметра будет передан msecs.
outgoingMessage.socket
Ссылка на нижележащий сокет. Обычно пользователям не требуется обращаться к этому свойству.
После вызова outgoingMessage.end() значение этого свойства будет сброшено в null.
outgoingMessage.uncork()
outgoingMessage.writableCorked
Количество вызовов outgoingMessage.cork().
outgoingMessage.writableEnded
Равно true, если был вызван outgoingMessage.end(). Это свойство не указывает, были ли данные переданы. Для этого используйте message.writableFinished.
outgoingMessage.writableFinished
Равно true, если все данные переданы в нижележащую систему.
outgoingMessage.writableHighWaterMark
Значение highWaterMark назначенного нижележащего сокета. Если сокет не назначен, используется уровень буфера по умолчанию, при котором writable.write() начинает возвращать false (16384).
outgoingMessage.writableLength
Количество байтов в буфере.
outgoingMessage.writableObjectMode
Всегда false.
outgoingMessage.write(chunk[, encoding][, callback])
-
chunk<string> | <Buffer> | <Uint8Array> -
encoding<string> По умолчанию:utf8 -
callback<Function> - Возвращает: <boolean>
Отправляет фрагмент тела сообщения. Этот метод можно вызывать несколько раз.
Аргумент encoding имеет значение только в том случае, если chunk является строкой. По умолчанию используется 'utf8'.
Аргумент callback необязателен и будет вызван после передачи этого фрагмента данных.
Возвращает true, если все данные успешно переданы в буфер ядра. Возвращает false, если все данные или их часть поставлены в очередь в памяти пользователя. Когда буфер снова освободится, возникнет событие 'drain'.
http.METHODS
Список методов HTTP, поддерживаемых анализатором.
http.STATUS_CODES
Коллекция всех стандартных кодов состояния ответа HTTP и кратких описаний каждого из них. Например, http.STATUS_CODES[404] === 'Not Found'.
http.createServer([options][, requestListener])
-
options<Object>-
connectionsCheckingInterval: Задает интервал в миллисекундах для проверки тайм-аута запроса и заголовков в неполных запросах. По умолчанию:30000. -
headersTimeout: Задает время ожидания в миллисекундах для получения всех HTTP-заголовков от клиента. Подробнее см. в разделеserver.headersTimeout. По умолчанию:60000. -
highWaterMark<number> При необходимости переопределяет параметрыsocketиreadableHighWaterMarkвсехwritableHighWaterMark. Это влияет на свойствоhighWaterMarkобъектовIncomingMessageиServerResponse. По умолчанию: см.stream.getDefaultHighWaterMark(). -
insecureHTTPParser<boolean> Если задано значениеtrue, будет использоваться анализатор HTTP с включенными флагами допуска. Следует избегать использования небезопасного анализатора. Подробнее см.--insecure-http-parser. По умолчанию:false. -
IncomingMessage<http.IncomingMessage> Указывает используемый классIncomingMessage. Это полезно для расширения исходногоIncomingMessage. По умолчанию:IncomingMessage. -
joinDuplicateHeaders<boolean> Если задано значениеtrue, этот параметр позволяет объединять значения строк полей нескольких заголовков запроса через запятую (,), а не отбрасывать дубликаты. Дополнительные сведения см. в разделеmessage.headers. По умолчанию:false. -
keepAlive<boolean> Если задано значениеtrue, функция keep-alive включается на сокете сразу после получения нового входящего подключения, аналогично тому, как это происходит в [socket.setKeepAlive([enable][, initialDelay])][socket.setKeepAlive(enable, initialDelay)]. По умолчанию:false. -
keepAliveInitialDelay<number> Если задано положительное число, оно определяет начальную задержку перед отправкой первой пробы keepalive через неактивный сокет. По умолчанию:0. -
keepAliveTimeout: Время бездействия в миллисекундах, в течение которого сервер должен ожидать дополнительные входящие данные после отправки последнего ответа, прежде чем сокет будет уничтожен. Подробнее см. в разделеserver.keepAliveTimeout. По умолчанию:5000. -
maxHeaderSize<number> При необходимости переопределяет значение--max-http-header-sizeдля запросов, получаемых этим сервером, то есть максимальную длину заголовков запроса в байтах. По умолчанию: 16384 (16 КиБ). -
noDelay<boolean> Если задано значениеtrue, алгоритм Нейгла отключается сразу после получения нового входящего подключения. По умолчанию:true. -
requestTimeout: Задает время ожидания в миллисекундах для получения всего запроса от клиента. Подробнее см. в разделеserver.requestTimeout. По умолчанию:300000. -
requireHostHeader<boolean> Если задано значениеtrue, сервер принудительно возвращает код состояния 400 (Bad Request) для любого сообщения HTTP/1.1 без заголовка Host (как того требует спецификация). По умолчанию:true. -
ServerResponse<http.ServerResponse> Указывает используемый классServerResponse. Это полезно для расширения исходногоServerResponse. По умолчанию:ServerResponse. -
uniqueHeaders<Array> Список заголовков ответа, которые следует отправлять только один раз. Если значение заголовка является массивом, его элементы будут объединены с помощью;. -
rejectNonStandardBodyWrites<boolean> Если задано значениеtrue, при записи в HTTP-ответ без тела будет выброшена ошибка. По умолчанию:false.
-
-
requestListener<Function> -
Возвращает: <http.Server>
Возвращает новый экземпляр http.Server.
Функция requestListener автоматически добавляется в событие 'request'.
Модули JavaScript
import http from 'node:http';
// Create a local server to receive data from
const server = http.createServer((req, res) => {
res.writeHead(200, { 'Content-Type': 'application/json' });
res.end(JSON.stringify({
data: 'Hello World!',
}));
});
server.listen(8000);CommonJS
const http = require('node:http');
// Create a local server to receive data from
const server = http.createServer((req, res) => {
res.writeHead(200, { 'Content-Type': 'application/json' });
res.end(JSON.stringify({
data: 'Hello World!',
}));
});
server.listen(8000);Модули JavaScript
import http from 'node:http';
// Create a local server to receive data from
const server = http.createServer();
// Listen to the request event
server.on('request', (request, res) => {
res.writeHead(200, { 'Content-Type': 'application/json' });
res.end(JSON.stringify({
data: 'Hello World!',
}));
});
server.listen(8000);CommonJS
const http = require('node:http');
// Create a local server to receive data from
const server = http.createServer();
// Listen to the request event
server.on('request', (request, res) => {
res.writeHead(200, { 'Content-Type': 'application/json' });
res.end(JSON.stringify({
data: 'Hello World!',
}));
});
server.listen(8000);
http.get(options[, callback])
http.get(url[, options][, callback])
-
url<string> | <URL> -
options<Object> Принимает те жеoptions, что иhttp.request(); по умолчанию используется метод GET. -
callback<Function> - Возвращает: <http.ClientRequest>
Поскольку большинство запросов — это запросы GET без тела, Node.js предоставляет этот вспомогательный метод. Единственное отличие этого метода от http.request() состоит в том, что он задает метод GET по умолчанию и автоматически вызывает req.end(). Функция обратного вызова должна обработать данные ответа, как указано в разделе http.ClientRequest.
Функция callback вызывается с одним аргументом — экземпляром http.IncomingMessage.
Пример получения JSON:
http.get('http://localhost:8000/', (res) => {
const { statusCode } = res;
const contentType = res.headers['content-type'];
let error;
// Any 2xx status code signals a successful response but
// here we're only checking for 200.
if (statusCode !== 200) {
error = new Error('Request Failed.\n' +
`Status Code: ${statusCode}`);
} else if (!/^application\/json/.test(contentType)) {
error = new Error('Invalid content-type.\n' +
`Expected application/json but received ${contentType}`);
}
if (error) {
console.error(error.message);
// Consume response data to free up memory
res.resume();
return;
}
res.setEncoding('utf8');
let rawData = '';
res.on('data', (chunk) => { rawData += chunk; });
res.on('end', () => {
try {
const parsedData = JSON.parse(rawData);
console.log(parsedData);
} catch (e) {
console.error(e.message);
}
});
}).on('error', (e) => {
console.error(`Got error: ${e.message}`);
});
// Create a local server to receive data from
const server = http.createServer((req, res) => {
res.writeHead(200, { 'Content-Type': 'application/json' });
res.end(JSON.stringify({
data: 'Hello World!',
}));
});
server.listen(8000); copy
http.globalAgent
Глобальный экземпляр Agent, используемый по умолчанию для всех HTTP-клиентских запросов. Отличается от конфигурации Agent по умолчанию тем, что keepAlive включен, а значение timeout составляет 5 секунд.
http.maxHeaderSize
Свойство только для чтения, указывающее максимально допустимый размер HTTP-заголовков в байтах. По умолчанию — 16 КиБ. Настраивается с помощью параметра CLI --max-http-header-size.
Это значение можно переопределить для серверов и клиентских запросов, передав параметр maxHeaderSize.
http.request(options[, callback])
http.request(url[, options][, callback])
-
url<string> | <URL> -
options<Object>-
agent<http.Agent> | <boolean> Управляет поведениемAgent. Возможные значения:-
undefined(по умолчанию): использоватьhttp.globalAgentдля этого узла и порта. -
Agentобъект: явно использовать переданныйAgent. -
false: использовать новыйAgentсо значениями по умолчанию.
-
-
auth<string> Данные для базовой аутентификации ('user:password'), используемые для формирования заголовка Authorization. -
createConnection<Function> Функция, создающая сокет/поток для запроса, если параметрagentне используется. Это можно использовать, чтобы не создавать собственный классAgentтолько для переопределения функцииcreateConnectionпо умолчанию. Подробнее см. в разделеagent.createConnection(). Допустимым возвращаемым значением является любой потокDuplex. -
defaultPort<number> Порт протокола по умолчанию. По умолчанию:agent.defaultPort, если используетсяAgent, иначеundefined. -
family<number> Семейство IP-адресов, используемое при разрешенииhostилиhostname. Допустимые значения:4или6. Если значение не указано, будут использоваться IPv4 и IPv6. -
headers<Object> Объект, содержащий заголовки запроса. -
hints<number> Необязательные подсказкиdns.lookup(). -
host<string> Доменное имя или IP-адрес сервера, которому отправляется запрос. По умолчанию:'localhost'. -
hostname<string> Псевдоним дляhost. Для поддержкиurl.parse()будет использоватьсяhostname, если указаны оба параметра —hostиhostname. -
insecureHTTPParser<boolean> Если установлено значениеtrue, будет использоваться HTTP-парсер с включёнными флагами снисходительного разбора. Не рекомендуется использовать небезопасный парсер. Подробнее см. в разделе--insecure-http-parser. По умолчанию:false -
joinDuplicateHeaders<boolean> Объединяет значения строк полей нескольких заголовков запроса с помощью,вместо удаления дубликатов. Подробнее см. в разделеmessage.headers. По умолчанию:false. -
localAddress<string> Локальный интерфейс для привязки сетевых соединений. -
localPort<number> Локальный порт, с которого устанавливается соединение. -
lookup<Function> Пользовательская функция поиска. По умолчанию:dns.lookup(). -
maxHeaderSize<number> Позволяет переопределить значение--max-http-header-size(максимальную длину заголовков ответа в байтах) для ответов, полученных от сервера. По умолчанию: 16384 (16 КиБ). -
method<string> Строка, задающая метод HTTP-запроса. По умолчанию:'GET'. -
path<string> Путь запроса. При наличии должен включать строку запроса. Например:'/index.html?page=12'. Если путь запроса содержит недопустимые символы, возникает исключение. В настоящее время отклоняются только пробелы, но в будущем это может измениться. По умолчанию:'/'. -
port<number> Порт удалённого сервера. По умолчанию:defaultPort, если он задан, иначе80. -
protocol<string> Используемый протокол. По умолчанию:'http:'. -
setHost<boolean>: Указывает, следует ли автоматически добавлять заголовокHost. По умолчанию —true. -
signal<AbortSignal>: AbortSignal, который можно использовать для прерывания выполняющегося запроса. -
socketPath<string> Доменный сокет Unix. Нельзя использовать, если указан один из параметровhostилиport, поскольку они задают TCP-сокет. -
timeout<number>: Число, задающее время ожидания сокета в миллисекундах. Оно задаёт время ожидания до подключения сокета. -
uniqueHeaders<Array> Список заголовков запроса, которые следует отправлять только один раз. Если значение заголовка является массивом, его элементы будут объединены с помощью;.
-
-
callback<Function> - Возвращает: <http.ClientRequest>
Также поддерживаются options в socket.connect().
Node.js поддерживает несколько соединений с каждым сервером для выполнения HTTP-запросов. Эта функция позволяет отправлять запросы прозрачным для пользователя образом.
url может быть строкой или объектом URL. Если url — строка, она автоматически разбирается с помощью new URL(). Если это объект URL, он автоматически преобразуется в обычный объект options.
Если указаны и url, и options, объекты объединяются, причём свойства options имеют приоритет.
Необязательный параметр callback будет добавлен как одноразовый обработчик события 'response'.
http.request() возвращает экземпляр класса http.ClientRequest. Экземпляр ClientRequest является потоком для записи. Чтобы загрузить файл с помощью POST-запроса, нужно записать данные в объект ClientRequest.
Модули JavaScript
import http from 'node:http';
import { Buffer } from 'node:buffer';
const postData = JSON.stringify({
'msg': 'Hello World!',
});
const options = {
hostname: 'www.google.com',
port: 80,
path: '/upload',
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Content-Length': Buffer.byteLength(postData),
},
};
const req = http.request(options, (res) => {
console.log(`STATUS: ${res.statusCode}`);
console.log(`HEADERS: ${JSON.stringify(res.headers)}`);
res.setEncoding('utf8');
res.on('data', (chunk) => {
console.log(`BODY: ${chunk}`);
});
res.on('end', () => {
console.log('No more data in response.');
});
});
req.on('error', (e) => {
console.error(`problem with request: ${e.message}`);
});
// Write data to request body
req.write(postData);
req.end();CommonJS
const http = require('node:http');
const postData = JSON.stringify({
'msg': 'Hello World!',
});
const options = {
hostname: 'www.google.com',
port: 80,
path: '/upload',
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Content-Length': Buffer.byteLength(postData),
},
};
const req = http.request(options, (res) => {
console.log(`STATUS: ${res.statusCode}`);
console.log(`HEADERS: ${JSON.stringify(res.headers)}`);
res.setEncoding('utf8');
res.on('data', (chunk) => {
console.log(`BODY: ${chunk}`);
});
res.on('end', () => {
console.log('No more data in response.');
});
});
req.on('error', (e) => {
console.error(`problem with request: ${e.message}`);
});
// Write data to request body
req.write(postData);
req.end();В примере был вызван req.end(). При использовании http.request() всегда нужно вызывать req.end(), чтобы обозначить завершение запроса, даже если в тело запроса ничего не записывается.
Если во время запроса возникнет ошибка (например, при разрешении DNS, на уровне TCP или при разборе HTTP), на возвращённом объекте запроса будет сгенерировано событие 'error'. Как и для всех событий 'error', если обработчики не зарегистрированы, ошибка будет выброшена.
Следует обратить внимание на несколько специальных заголовков.
-
Отправка заголовка 'Connection: keep-alive' уведомляет Node.js о том, что соединение с сервером следует поддерживать открытым до следующего запроса.
-
Отправка заголовка 'Content-Length' отключает кодирование с передачей блоками, используемое по умолчанию.
-
Отправка заголовка 'Expect' немедленно отправляет заголовки запроса. Обычно при отправке 'Expect: 100-continue' следует задать и время ожидания, и обработчик события
'continue'. Подробнее см. в разделе 8.2.3 RFC 2616. -
Отправка заголовка Authorization переопределяет использование параметра
authдля формирования данных базовой аутентификации.
Пример использования URL в качестве options:
const options = new URL('http://abc:xyz@example.com');
const req = http.request(options, (res) => {
// ...
}); copy При успешном запросе будут сгенерированы следующие события в указанном порядке:
'socket'-
'response'-
'data'произвольное количество раз для объектаres(событие'data'не будет сгенерировано, если тело ответа пусто, например при большинстве перенаправлений) -
'end'для объектаres
-
'close'
В случае ошибки соединения будут сгенерированы следующие события:
'socket''error''close'
Если соединение неожиданно закрывается до получения ответа, будут сгенерированы следующие события в указанном порядке:
'socket'-
'error'с ошибкой с сообщением'Error: socket hang up'и кодом'ECONNRESET' 'close'
Если соединение неожиданно закрывается после получения ответа, будут сгенерированы следующие события в указанном порядке:
'socket'-
'response'-
'data'произвольное количество раз для объектаres
-
- (здесь соединение закрывается)
-
'aborted'для объектаres 'close'-
'error'для объектаresс ошибкой с сообщением'Error: aborted'и кодом'ECONNRESET' -
'close'для объектаres
Если req.destroy() вызывается до назначения сокета, будут сгенерированы следующие события в указанном порядке:
- (здесь вызывается
req.destroy()) -
'error'с ошибкой с сообщением'Error: socket hang up'и кодом'ECONNRESET'либо с ошибкой, с которой был вызванreq.destroy() 'close'
Если req.destroy() вызывается до успешного установления соединения, будут сгенерированы следующие события в указанном порядке:
'socket'- (здесь вызывается
req.destroy()) -
'error'с ошибкой с сообщением'Error: socket hang up'и кодом'ECONNRESET'либо с ошибкой, с которой был вызванreq.destroy() 'close'
Если req.destroy() вызывается после получения ответа, будут сгенерированы следующие события в указанном порядке:
'socket'-
'response'-
'data'произвольное количество раз для объектаres
-
- (здесь вызывается
req.destroy()) -
'aborted'для объектаres 'close'-
'error'для объектаresс ошибкой с сообщением'Error: aborted'и кодом'ECONNRESET'либо с ошибкой, с которой был вызванreq.destroy() -
'close'для объектаres
Если req.abort() вызывается до назначения сокета, будут сгенерированы следующие события в указанном порядке:
- (здесь вызывается
req.abort()) 'abort''close'
Если req.abort() вызывается до успешного установления соединения, будут сгенерированы следующие события в указанном порядке:
'socket'- (здесь вызывается
req.abort()) 'abort'-
'error'с ошибкой с сообщением'Error: socket hang up'и кодом'ECONNRESET' 'close'
Если req.abort() вызывается после получения ответа, будут сгенерированы следующие события в указанном порядке:
'socket'-
'response'-
'data'произвольное количество раз для объектаres
-
- (здесь вызывается
req.abort()) 'abort'-
'aborted'для объектаres -
'error'для объектаresс ошибкой с сообщением'Error: aborted'и кодом'ECONNRESET'. 'close'-
'close'для объектаres
Установка параметра timeout или использование функции setTimeout() не прерывает запрос и не приводит ни к каким другим действиям, кроме добавления события 'timeout'.
Передача AbortSignal с последующим вызовом abort() для соответствующего AbortController действует так же, как вызов .destroy() для запроса. В частности, событие 'error' будет сгенерировано с ошибкой с сообщением 'AbortError: The operation was aborted', кодом 'ABORT_ERR' и cause, если он был указан.
http.validateHeaderName(name[, label])
Выполняет низкоуровневую проверку переданного name, такую же, как при вызове res.setHeader(name, value).
Передача недопустимого значения в качестве name приведёт к выбрасыванию TypeError, обозначенной кодом code: 'ERR_INVALID_HTTP_TOKEN'.
Перед передачей заголовков HTTP-запросу или ответу использовать этот метод необязательно. Модуль HTTP проверит такие заголовки автоматически.
Пример:
Модули JavaScript
import { validateHeaderName } from 'node:http';
try {
validateHeaderName('');
} catch (err) {
console.error(err instanceof TypeError); // --> true
console.error(err.code); // --> 'ERR_INVALID_HTTP_TOKEN'
console.error(err.message); // --> 'Header name must be a valid HTTP token [""]'
}CommonJS
const { validateHeaderName } = require('node:http');
try {
validateHeaderName('');
} catch (err) {
console.error(err instanceof TypeError); // --> true
console.error(err.code); // --> 'ERR_INVALID_HTTP_TOKEN'
console.error(err.message); // --> 'Header name must be a valid HTTP token [""]'
}
http.validateHeaderValue(name, value)
Выполняет низкоуровневую проверку переданного value, такую же, как при вызове res.setHeader(name, value).
Передача недопустимого значения в качестве value приведёт к выбрасыванию TypeError.
- Ошибка неопределённого значения обозначается кодом
code: 'ERR_HTTP_INVALID_HEADER_VALUE'. - Ошибка недопустимого символа в значении обозначается кодом
code: 'ERR_INVALID_CHAR'.
Перед передачей заголовков HTTP-запросу или ответу использовать этот метод необязательно. Модуль HTTP проверит такие заголовки автоматически.
Примеры:
Модули JavaScript
import { validateHeaderValue } from 'node:http';
try {
validateHeaderValue('x-my-header', undefined);
} catch (err) {
console.error(err instanceof TypeError); // --> true
console.error(err.code === 'ERR_HTTP_INVALID_HEADER_VALUE'); // --> true
console.error(err.message); // --> 'Invalid value "undefined" for header "x-my-header"'
}
try {
validateHeaderValue('x-my-header', 'oʊmɪɡə');
} catch (err) {
console.error(err instanceof TypeError); // --> true
console.error(err.code === 'ERR_INVALID_CHAR'); // --> true
console.error(err.message); // --> 'Invalid character in header content ["x-my-header"]'
}CommonJS
const { validateHeaderValue } = require('node:http');
try {
validateHeaderValue('x-my-header', undefined);
} catch (err) {
console.error(err instanceof TypeError); // --> true
console.error(err.code === 'ERR_HTTP_INVALID_HEADER_VALUE'); // --> true
console.error(err.message); // --> 'Invalid value "undefined" for header "x-my-header"'
}
try {
validateHeaderValue('x-my-header', 'oʊmɪɡə');
} catch (err) {
console.error(err instanceof TypeError); // --> true
console.error(err.code === 'ERR_INVALID_CHAR'); // --> true
console.error(err.message); // --> 'Invalid character in header content ["x-my-header"]'
}
http.setMaxIdleHTTPParsers(max)
-
max<number> По умолчанию:1000.
Задаёт максимальное количество простаивающих HTTP-парсеров.
© Joyent, Inc. and other Node contributors
Licensed under the MIT License.
Node.js is a trademark of Joyent, Inc. and is used with its permission.
We are not endorsed by or affiliated with Joyent.
https://nodejs.org/dist/latest-v20.x/docs/api/http.html