HTTP
Для использования HTTP-сервера и клиента необходимо require('http').
Интерфейсы HTTP в Node.js разработаны для поддержки многих функций протокола, которые традиционно были сложными в использовании. В частности, больших, возможно, фрагментированных, сообщений. Интерфейс заботится о том, чтобы не буферизовать запросы или ответы целиком — пользователь может передавать данные потоками.
Заголовки сообщений HTTP представляются объектом такого типа:
{ 'content-length': '123',
'content-type': 'text/plain',
'connection': 'keep-alive',
'host': 'mysite.com',
'accept': '*/*' }
Ключи записаны в нижнем регистре. Значения не изменяются.
Для поддержки всего спектра возможных приложений 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', 'mysite.com', 'accepT', '*/*' ]
Класс: http.Agent
Объект Agent отвечает за управление сохранением и повторным использованием соединений для HTTP-клиентов. Он поддерживает очередь ожидающих запросов для заданного хоста и порта, повторно используя одно сокет-соединение для каждого, пока очередь не опустеет, в этот момент сокет либо уничтожается, либо помещается в пул, где он хранится для повторного использования для запросов к тому же хосту и порту. Либо уничтожается, либо помещается в пул, зависит от keepAlive параметра.
В пулированных соединениях включен TCP Keep-Alive, но серверы все равно могут закрывать неактивные соединения, в этом случае они удаляются из пула, и при отправке нового HTTP-запроса для данного хоста и порта устанавливается новое соединение. Серверы также могут отказать в разрешении нескольких запросов через одно соединение, в этом случае соединение должно быть переустановлено для каждого запроса и не может быть помещено в пул. Agent по-прежнему будет отправлять запросы на этот сервер, но каждый из них будет осуществляться через новое соединение.
При закрытии соединения клиентом или сервером оно удаляется из пула. Любые неиспользуемые сокеты в пуле будут удалены, чтобы не удерживать процесс Node.js, когда нет ожидающих запросов. (см. socket.unref()).
Хорошей практикой является destroy() экземпляр Agent при его выходе из использования, так как неиспользуемые сокеты потребляют ресурсы ОС.
Сокеты удаляются из агента, когда сокет отправляет событие 'close' или событие 'agentRemove'. При необходимости удерживать один HTTP-запрос открытым в течение длительного времени без сохранения в агенте, можно выполнить следующее:
http.get(options, (res) => {
// Do stuff
}).on('socket', (socket) => {
socket.emit('agentRemove');
});
Агент также может быть использован для отдельного запроса. Указав {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
});
new Agent([options])
-
options<Объект> Набор настраиваемых параметров для настройки агента. Может содержать следующие поля:-
keepAlive<логическое значение> Сохранять сокеты даже при отсутствии ожидающих запросов, чтобы их можно было использовать для будущих запросов без необходимости повторного установления TCP-соединения. По умолчанию:false. -
keepAliveMsecs<число> При использовании опцииkeepAlive, задаёт начальную задержку (initial delay) для пакетов TCP Keep-Alive. Игнорируется, когда параметрkeepAliveимеет значениеfalseилиundefined. По умолчанию:1000. -
maxSockets<число> Максимальное количество сокетов, разрешённых на хост. По умолчанию:Infinity. -
maxFreeSockets<число> Максимальное число сокетов, которые должны оставаться открытыми в свободном состоянии. Актуально только еслиkeepAliveустановлено вtrue. По умолчанию:256.
-
По умолчанию используемый http.globalAgent агент, используемый http.request() имеет все эти значения установленные по умолчанию.
Для настройки любого из них необходимо создать экземпляр пользовательского http.Agent.
const http = require('http');
const keepAliveAgent = new http.Agent({ keepAlive: true });
options.agent = keepAliveAgent;
http.request(options, onResponseCallback);
agent.createConnection(options[, callback])
-
options<Объект> Параметры, содержащие данные соединения. Обратитесь кnet.createConnection()для формата параметров -
callback<Функция> Функция обратного вызова, которая получает созданный сокет - Возвращает: <net.Socket>
Создаёт сокет/поток для использования в HTTP-запросах.
По умолчанию, эта функция эквивалентна net.createConnection(). Однако, пользовательские агенты могут переопределить этот метод в случае необходимости большей гибкости.
Сокет/поток может быть предоставлен двумя способами: возвратом сокета/потока из этой функции или передачей сокета/потока в callback.
callback имеет подпись (err, stream).
agent.keepSocketAlive(socket)
-
socket<net.Socket>
Вызывается, когда socket отделяется от запроса и может быть сохранён агентом. По умолчанию поведение:
socket.setKeepAlive(true, this.keepAliveMsecs); socket.unref(); return true;
Этот метод может быть переопределён конкретным подклассом Agent. Если этот метод возвращает ложное значение, сокет будет уничтожен вместо сохранения для использования с последующим запросом.
agent.reuseSocket(socket, request)
-
socket<net.Socket> -
request<http.ClientRequest>
Вызывается, когда socket присоединяется к request после сохранения из-за параметров keep-alive. По умолчанию поведение:
socket.ref();
Этот метод может быть переопределён конкретным подклассом Agent.
agent.destroy()
Уничтожить все сокеты, которые в настоящее время используются агентом.
Обычно это не требуется. Однако, если включён параметр keepAlive, рекомендуется явно завершить работу агента, когда он больше не будет использоваться. В противном случае сокеты могут оставаться открытыми довольно долго, прежде чем сервер их закроет.
agent.freeSockets
Объект, содержащий массивы сокетов, которые в настоящее время ожидают использования агентом, когда keepAlive включён. Не изменяйте.
agent.getName(options)
-
options<Объект> Набор параметров, предоставляющих информацию для генерации имени-
host<строка> Доменное имя или IP-адрес сервера, к которому необходимо отправить запрос -
port<число> Порт удалённого сервера -
localAddress<строка> Локальный интерфейс для привязки сетевых соединений при отправке запроса -
family<целое число> Должно быть 4 или 6, если это не равноundefined.
-
- Возвращает: <строка>
Получает уникальное имя для набора параметров запроса, чтобы определить, можно ли повторно использовать соединение. Для HTTP-агента возвращает host:port:localAddress или host:port:localAddress:family. Для HTTPS-агента имя включает CA, сертификат, шифры и другие параметры HTTPS/TLS, определяющие возможность повторного использования сокета.
agent.maxFreeSockets
По умолчанию равен 256. Для агентов с keepAlive включённым, это устанавливает максимальное количество сокетов, которые будут оставлены открытыми в свободном состоянии.
agent.maxSockets
По умолчанию установлено в Infinity. Определяет, сколько одновременных сокетов агент может иметь открытыми на каждый источник. Источник — это возвращаемое значение agent.getName().
agent.requests
Объект, содержащий очереди запросов, которые еще не были назначены сокетам. Не изменяйте.
agent.sockets
Объект, содержащий массивы сокетов, которые в настоящее время используются агентом. Не изменяйте.
Класс: http.ClientRequest
Этот объект создается внутри и возвращается из 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' не будет выполнено. Кроме того, пока данные не будут прочитаны, они будут занимать память, что в конечном итоге может привести к ошибке «процесс без памяти».
Примечание: Node.js не проверяет, равны ли Content-Length и длина переданного тела.
Запрос реализует интерфейс потока Writable Stream. Это EventEmitter с последующими событиями:
Событие: 'abort'
Издается, когда клиент прервал запрос. Это событие излучается только при первом вызове abort().
Событие: 'connect'
-
response<http.IncomingMessage> -
socket<net.Socket> -
head<Буфер>
Издается каждый раз, когда сервер отвечает на запрос методом CONNECT. Если за этим событием не следят, клиенты, получившие метод CONNECT, прервут свои соединения.
Пара клиент-сервер, демонстрирующая, как прослушать событие 'connect':
const http = require('http');
const net = require('net');
const url = require('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, cltSocket, head) => {
// connect to an origin server
const srvUrl = url.parse(`http://${req.url}`);
const srvSocket = net.connect(srvUrl.port, srvUrl.hostname, () => {
cltSocket.write('HTTP/1.1 200 Connection Established\r\n' +
'Proxy-agent: Node.js-Proxy\r\n' +
'\r\n');
srvSocket.write(head);
srvSocket.pipe(cltSocket);
cltSocket.pipe(srvSocket);
});
});
// now that proxy is running
proxy.listen(1337, '127.0.0.1', () => {
// make a request to a tunneling proxy
const options = {
port: 1337,
hostname: '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'. Это инструкция, что клиент должен отправить тело запроса.
Событие: 'response'
-
response<http.IncomingMessage>
Издается при получении ответа на этот запрос. Это событие излучается только один раз.
Событие: 'socket'
-
socket<net.Socket>
Издается после назначения сокета этому запросу.
Событие: 'timeout'
Издается, когда базовый сокет отключается из-за бездействия. Это только оповещает о том, что сокет был простаивал. Запрос необходимо прервать вручную.
См. также: request.setTimeout()
Событие: 'upgrade'
-
response<http.IncomingMessage> -
socket<net.Socket> -
head<Буфер>
Издается каждый раз, когда сервер отвечает на запрос с обновлением. Если за этим событием не следят, клиенты, получившие заголовок обновления, прервут свои соединения.
Пара клиент-сервер, демонстрирующая, как прослушать событие 'upgrade':
const http = require('http');
// Create an HTTP server
const srv = http.createServer((req, res) => {
res.writeHead(200, { 'Content-Type': 'text/plain' });
res.end('okay');
});
srv.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
srv.listen(1337, '127.0.0.1', () => {
// make a request
const options = {
port: 1337,
hostname: '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.aborted
Если запрос был прерван, это значение — время прерывания запроса в миллисекундах с 00:00:00 UTC 1 января 1970 года.
request.connection
См. request.socket
request.end([data[, encoding]][, callback])
Завершает отправку запроса. Если какие-либо части тела не отправлены, они будут переданы в поток. Если запрос разбивается на фрагменты, это отправит завершающий '0\r\n\r\n'.
Если data указан, это эквивалентно вызову request.write(data, encoding) и request.end(callback).
Если callback указан, он будет вызван, когда поток запроса будет завершен.
request.flushHeaders()
Очистка заголовков запроса.
По причинам эффективности Node.js обычно буферизует заголовки запроса до тех пор, пока не будет вызван request.end() или не будет записан первый фрагмент данных запроса. Затем он пытается упаковать заголовки и данные запроса в один пакет TCP.
Это обычно желательно (это экономит один обмен TCP), но не тогда, когда первые данные отправляются, возможно, намного позже. request.flushHeaders() обходит оптимизацию и запускает запрос.
request.getHeader(name)
Читает заголовок запроса. Обратите внимание, что имя не учитывает регистр.
Пример:
const contentType = request.getHeader('Content-Type');
request.removeHeader(name)
-
name<строка>
Удаляет уже определенный заголовок в объекте заголовков.
Пример:
request.removeHeader('Content-Type');
request.setHeader(name, value)
Устанавливает одно значение заголовка для объекта заголовков. Если этот заголовок уже существует в заголовках, которые будут отправлены, его значение будет заменено. Используйте массив строк, чтобы отправить несколько заголовков с одинаковым именем.
Пример:
request.setHeader('Content-Type', 'application/json');
или
request.setHeader('Set-Cookie', ['type=ninja', 'language=javascript']);
request.setNoDelay([noDelay])
-
noDelay<булево>
После назначения сокета этому запросу и его подключения будет вызван socket.setNoDelay().
request.setSocketKeepAlive([enable][, initialDelay])
После назначения сокета этому запросу и его подключения будет вызван метод socket.setKeepAlive().
request.setTimeout(timeout[, callback])
-
timeout<number> Миллисекунды до истечения времени ожидания запроса. -
callback<Function> Необязательная функция, которая вызывается при истечении времени ожидания. То же самое, что привязка к событиюtimeout.
Если сокет не назначен этому запросу, то socket.setTimeout() будет вызван немедленно. В противном случае socket.setTimeout() будет вызван после подключения назначенного сокета.
Возвращает request.
request.socket
Ссылка на базовый сокет. Обычно пользователям не нужно обращаться к этому свойству. В частности, сокет не будет излучать события 'readable' из-за того, как анализатор протокола прикрепляется к сокету. После response.end(), свойство обнуляется. К свойству socket также можно обратиться через request.connection.
Пример:
const http = require('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
});
request.write(chunk[, encoding][, callback])
-
chunk<string> | <Buffer> -
encoding<string> -
callback<Function>
Отправляет часть тела. Вызывая этот метод многократно, можно отправлять тело запроса на сервер — в этом случае рекомендуется использовать заголовок ['Transfer-Encoding', 'chunked'] при создании запроса.
Аргумент encoding необязателен и применяется только когда chunk — строка. По умолчанию 'utf8'.
Аргумент callback необязателен и вызывается, когда этот фрагмент данных сбрасывается.
Возвращает true если все данные успешно сброшены в буфер ядра. Возвращает false если все или часть данных были помещены в память пользователя. Событие 'drain' будет излучаться, когда буфер освободится.
Класс: 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<net.Socket>
Если соединение клиента излучает событие 'error' , оно будет передано сюда. Обработчик этого события отвечает за закрытие/уничтожение базового сокета. Например, можно более корректно закрыть сокет с помощью пользовательского HTTP ответа вместо резкого разрыва соединения.
По умолчанию сокет закрывается с HTTP-ответом '400 Bad Request', если это возможно, в противном случае сокет немедленно уничтожается.
socket — объект net.Socket, из которого произошла ошибка.
const http = require('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: исходный пакет текущего запроса.
Событие: 'close'
Излучается при закрытии сервера.
Событие: 'connect'
-
request<http.IncomingMessage> Аргументы для HTTP запроса, как в событии'request' -
socket<net.Socket> Сеть сокет между сервером и клиентом -
head<Buffer> Первый пакет туннелируемого потока (может быть пустым)
Излучается каждый раз, когда клиент запрашивает HTTP CONNECT метод. Если это событие не обрабатывается, то подключения клиентов, запрашивающих CONNECT метод, будут закрыты.
После излучения этого события у сокета запроса не будет обработчика события 'data', поэтому его нужно будет связать, чтобы обработать данные, отправленные серверу по этому сокету.
Событие: 'connection'
-
socket<net.Socket>
Это событие излучается при установлении нового TCP потока. socket обычно объект типа net.Socket. Обычно пользователям не нужно обращаться к этому событию. В частности, сокет не будет излучать события 'readable' из-за того, как анализатор протокола прикрепляется к сокету. К socket также можно обратиться по адресу request.connection.
Примечание: это событие также может быть явно излучено пользователями для вставки подключений в HTTP сервер. В этом случае любой поток Duplex может быть передан.
Событие: 'request'
-
request<http.IncomingMessage> -
response<http.ServerResponse>
Излучается каждый раз, когда есть запрос. Обратите внимание, что может быть несколько запросов на одно соединение (в случае HTTP Keep-Alive соединений).
Событие: 'upgrade'
-
request<http.IncomingMessage> Аргументы для HTTP запроса, как в событии'request' -
socket<net.Socket> Сеть сокет между сервером и клиентом -
head<Buffer> Первый пакет обновлённого потока (может быть пустым)
Излучается каждый раз, когда клиент запрашивает HTTP обновление. Если это событие не обрабатывается, то подключения клиентов, запрашивающих обновление, будут закрыты.
После излучения этого события у сокета запроса не будет обработчика события 'data', поэтому его нужно будет связать, чтобы обработать данные, отправленные серверу по этому сокету.
server.close([callback])
-
callback<Function>
Останавливает сервер от принятия новых подключений. См. net.Server.close().
server.listen()
Запускает HTTP-сервер, прослушивающий соединения. Этот метод идентичен методу server.listen() из класса net.Server.
server.listening
Логическое значение, указывающее, прослушивает ли сервер соединения.
server.maxHeadersCount
-
<number> По умолчанию:
2000
Ограничивает максимальное количество входящих заголовков. Если значение равно 0, ограничение не применяется.
server.headersTimeout
-
<number> По умолчанию:
40000
Ограничивает время ожидания парсером получения полных HTTP-заголовков.
В случае бездействия применяются правила, определённые в [server.timeout][]. Однако это ограничение по бездействию всё ещё позволяет сохранять соединение открытым, если заголовки передаются очень медленно (по умолчанию до одного байта в 2 минуты). Для предотвращения этого, каждый раз при поступлении данных заголовков выполняется дополнительная проверка, не прошло ли более server.headersTimeout миллисекунд с момента установления соединения. Если проверка завершается неудачно, событие 'timeout' генерируется для объекта сервера, и (по умолчанию) сокет уничтожается. Подробнее о настройке поведения таймаута см. в [server.timeout][].
server.setTimeout([msecs][, callback])
-
msecs<number> По умолчанию:120000(2 минуты) -
callback<Function>
Устанавливает значение таймаута для сокетов и генерирует событие 'timeout' для объекта сервера, передавая сокет в качестве аргумента, если произошёл таймаут.
Если на объекте сервера существует обработчик события 'timeout', он будет вызван с таймаутировавшим сокетом в качестве аргумента.
По умолчанию значение таймаута сервера составляет 2 минуты, и сокеты автоматически уничтожаются при таймауте. Однако, если для события 'timeout' сервера назначен обратный вызов, таймауты необходимо обрабатывать явно.
Возвращает server.
server.timeout
-
<number> Таймаут в миллисекундах. По умолчанию:
120000(2 минуты).
Количество миллисекунд бездействия до того, как сокет считается таймаутировавшим.
Значение 0 отключит поведение таймаута для входящих соединений.
Примечание: Логика таймаута сокетов устанавливается при подключении, поэтому изменение этого значения влияет только на новые соединения с сервером, а не на существующие.
server.keepAliveTimeout
-
<number> Таймаут в миллисекундах. По умолчанию:
5000(5 секунд).
Количество миллисекунд бездействия, которое сервер должен ждать дополнительных входящих данных после завершения записи последнего ответа, прежде чем сокет будет уничтожен. Если сервер получает новые данные до истечения таймаута keep-alive, он сбрасывает обычный таймаут бездействия, т.е. server.timeout.
Значение 0 отключит поведение таймаута keep-alive для входящих соединений. Значение 0 заставит HTTP-сервер вести себя аналогично версиям Node.js до 8.0.0, в которых не было таймаута keep-alive.
Примечание: Логика таймаута сокетов устанавливается при подключении, поэтому изменение этого значения влияет только на новые соединения с сервером, а не на существующие.
Класс: http.ServerResponse
Этот объект создаётся HTTP-сервером внутренне — не пользователем. Он передаётся как второй параметр в событие 'request'.
Ответ реализует, но не наследуется от, интерфейса потока Writable Stream. Это объект EventEmitter со следующими событиями:
Событие: 'close'
Указывает, что базовое соединение было прервано до вызова response.end() или до возможности его сброса.
Событие: '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();
Попытка установить имя или значение поля заголовка, содержащего недопустимые символы, приведёт к тому, что будет выброшено исключение TypeError.
response.connection
См. response.socket.
response.end([data][, encoding][, callback])
-
data<string> | <Buffer> -
encoding<string> -
callback<Function>
Этот метод сигнализирует серверу о том, что все заголовки и тело ответа отправлены; сервер должен считать это сообщение завершённым. Метод response.end() обязательно должен вызываться для каждого ответа.
Если data указан, это эквивалентно вызову response.write(data, encoding), после которого следует response.end(callback).
Если callback указан, он будет вызван по завершении потока ответа.
response.finished
Логическое значение, указывающее, завершён ли ответ. Начинается как false. После выполнения response.end() значение станет true.
response.getHeader(name)
Считывает заголовок, который уже был поставлен в очередь, но ещё не отправлен клиенту. Обратите внимание, что имя регистронезависимо.
Пример:
const contentType = response.getHeader('content-type');
response.getHeaderNames()
- Возвращает: <Array>
Возвращает массив, содержащий уникальные имена текущих исходящих заголовков. Все имена заголовков находятся в нижнем регистре.
Пример:
response.setHeader('Foo', 'bar');
response.setHeader('Set-Cookie', ['foo=bar', 'bar=baz']);
const headerNames = response.getHeaderNames();
// headerNames === ['foo', 'set-cookie']
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'] }
response.hasHeader(name)
-
name<строка> - Возвращает: <логическое значение>
Возвращает true , если заголовок, идентифицированный как name, в данный момент установлен в исходящих заголовках. Обратите внимание, что соответствие имени заголовка не зависит от регистра.
Пример:
const hasContentType = response.hasHeader('content-type');
response.headersSent
Логическое значение (только для чтения). True, если заголовки были отправлены, иначе false.
response.removeHeader(name)
-
name<строка>
Удаляет заголовок, который запланирован для неявной отправки.
Пример:
response.removeHeader('Content-Encoding');
response.sendDate
Если значение true, заголовок Date будет автоматически сгенерирован и отправлен в ответе, если он ещё не присутствует в заголовках. По умолчанию значение true.
Это свойство следует отключать только для тестирования; HTTP требует заголовка Date в ответах.
response.setHeader(name, value)
-
name<строка> -
value<строка> | <массив строк>
Устанавливает значение одиночного заголовка для неявных заголовков. Если этот заголовок уже существует в заголовках, которые должны быть отправлены, его значение будет заменено. Используйте массив строк, чтобы отправить несколько заголовков с одинаковым именем.
Пример:
response.setHeader('Content-Type', 'text/html');
или
response.setHeader('Set-Cookie', ['type=ninja', 'language=javascript']);
Попытка установить имя или значение поля заголовка, содержащее недопустимые символы, приведёт к тому, что будет брошено исключение 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');
});
response.setTimeout(msecs[, callback])
Устанавливает значение таймаута сокета на msecs. Если указана функция обратного вызова, она добавляется как обработчик события 'timeout' объекта ответа.
Если ни к запросу, ни к ответу, ни к серверу не добавлен обработчик события 'timeout', сокеты будут уничтожаться при истечении времени ожидания. Если обработчик назначен для запроса, ответа или событий 'timeout' сервера, сокеты, истекшие по таймауту, необходимо обрабатывать явно.
Возвращает response.
response.socket
Ссылка на базовый сокет. Обычно пользователям не нужно обращаться к этому свойству. В частности, сокет не будет излучать события 'readable', поскольку анализатор протокола прикреплён к сокету. После response.end(), свойство обнуляется. Свойство socket также можно получить через response.connection.
Пример:
const http = require('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);
response.statusCode
При использовании неявных заголовков (если явно не вызывается response.writeHead()), это свойство управляет кодом состояния, который будет отправлен клиенту при сливе заголовков.
Пример:
response.statusCode = 404;
После отправки заголовка ответа клиенту это свойство указывает код состояния, который был отправлен.
response.statusMessage
При использовании неявных заголовков (если явно не вызывается response.writeHead()), это свойство управляет сообщением состояния, которое будет отправлено клиенту при сливе заголовков. Если оставить значение undefined , будет использовано стандартное сообщение для кода состояния.
Пример:
response.statusMessage = 'Not found';
После отправки заголовка ответа клиенту это свойство указывает сообщение состояния, которое было отправлено.
response.write(chunk[, encoding][, callback])
-
chunk<строка> | <Буфер> -
encoding<строка> По умолчанию:'utf8' -
callback<Функция> - Возвращает: <логическое значение>
Если этот метод вызывается, а response.writeHead() не был вызван, режим неявных заголовков будет переключён, и неявные заголовки будут слиты.
Отправляет фрагмент тела ответа. Этот метод можно вызывать несколько раз для последовательной передачи частей тела.
Обратите внимание, что в модуле http, тело ответа опущено, когда запрос является запросом HEAD. Аналогично, ответы 204 и 304 не должны содержать тело сообщения.
chunk может быть строкой или буфером. Если chunk является строкой, второй параметр указывает, как закодировать её в поток байтов. callback будет вызвана при сливе этого фрагмента данных.
Примечание: Это необработанное тело HTTP и не имеет ничего общего с многочастными кодировками тела верхнего уровня, которые могут использоваться.
При первом вызове response.write() он отправит буферизованные заголовки и первый фрагмент тела клиенту. При втором вызове response.write() Node.js предполагает передачу данных потоком и отправляет новые данные отдельно. То есть, ответ буферизуется до первого фрагмента тела.
Возвращает true , если все данные были успешно слиты в буфер ядра. Возвращает false , если все или часть данных были помещены в пользовательскую память. 'drain' будет излучаться, когда буфер снова освободится.
response.writeContinue()
Отправляет клиенту сообщение HTTP/1.1 100 Continue, указывая, что тело запроса следует отправить. См. событие 'checkContinue' на Server.
response.writeHead(statusCode[, statusMessage][, headers])
Отправляет заголовок ответа для запроса. Код состояния — это трёхзначный код состояния HTTP, например, 404. Последний аргумент, headers, — это заголовки ответа. В качестве второго аргумента можно необязательно указать удобочитаемое statusMessage сообщение.
Пример:
const body = 'hello world';
response.writeHead(200, {
'Content-Length': Buffer.byteLength(body),
'Content-Type': 'text/plain' });
Этот метод должен вызываться только один раз для сообщения, и его нужно вызывать до того, как будет вызван response.end().
Если response.write() или response.end() вызываются до вызова этого метода, будут рассчитаны неявные/изменяемые заголовки и вызван этот метод.
Когда заголовки были установлены с помощью 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');
});
Обратите внимание, что Content-Length указан в байтах, а не в символах. Приведенный выше пример работает, потому что строка 'hello world' содержит только символы с одним байтом. Если тело содержит символы с более высокими кодами, то следует использовать Buffer.byteLength() для определения количества байтов в данном кодировании. И Node.js не проверяет, равны ли Content-Length и длина переданного тела.
Попытка установить имя или значение поля заголовка, содержащие недопустимые символы, приведет к выбросу TypeError.
Класс: http.IncomingMessage
Объект IncomingMessage создается с помощью http.Server или http.ClientRequest и передается в качестве первого аргумента в событие 'request' и 'response' соответственно. Он может быть использован для доступа к статусу ответа, заголовкам и данным.
Он реализует интерфейс потока Readable Stream, а также следующие дополнительные события, методы и свойства.
Событие: 'aborted'
Выпускается, когда запрос был прерван.
Событие: 'close'
Указывает, что базовое соединение было закрыто. Как и 'end', это событие происходит только один раз на ответ.
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');
});
});
message.destroy([error])
-
error<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);
Дубликаты в исходных заголовках обрабатываются следующим образом в зависимости от имени заголовка:
- Дубликаты
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, илиuser-agentигнорируются. -
set-cookieвсегда является массивом. Дубликаты добавляются в массив. - Для всех остальных заголовков значения объединяются с помощью ', '.
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);
message.rawTrailers
Исходные ключи и значения трейлеров запроса/ответа в точном соответствии с полученными данными. Заполняется только при событии 'end'.
message.setTimeout(msecs, callback)
-
msecs<number> -
callback<Function>
Вызывает message.connection.setTimeout(msecs, callback).
Возвращает message.
message.socket
Объект net.Socket, связанный с подключением.
При поддержке HTTPS используйте request.socket.getPeerCertificate() для получения данных аутентификации клиента.
message.statusCode
Только для ответа, полученного от http.ClientRequest.
Трехзначный HTTP-код состояния ответа. Например, 404.
message.statusMessage
Только для ответа, полученного от http.ClientRequest.
Сообщение HTTP-состояния ответа (фраза причины). Например, OK или Internal Server Error.
message.trailers
Объект трейлеров запроса/ответа. Заполняется только при событии 'end'.
message.url
Только для запроса, полученного от http.Server.
Строка URL запроса. Содержит только URL, присутствующий в фактическом HTTP-запросе. Если запрос:
GET /status?name=ryan HTTP/1.1\r\n Accept: text/plain\r\n \r\n
то request.url будет:
'/status?name=ryan'
Для разбора URL на части можно использовать require('url').parse(request.url). Пример:
$ node
> require('url').parse('/status?name=ryan')
Url {
protocol: null,
slashes: null,
auth: null,
host: null,
port: null,
hostname: null,
hash: null,
search: '?name=ryan',
query: 'name=ryan',
pathname: '/status',
path: '/status?name=ryan',
href: '/status?name=ryan' }
Для извлечения параметров из строки запроса можно использовать функцию require('querystring').parse, или true можно передать в качестве второго аргумента в require('url').parse. Пример:
$ node
> require('url').parse('/status?name=ryan', true)
Url {
protocol: null,
slashes: null,
auth: null,
host: null,
port: null,
hostname: null,
hash: null,
search: '?name=ryan',
query: { name: 'ryan' },
pathname: '/status',
path: '/status?name=ryan',
href: '/status?name=ryan' }
http.METHODS
Список поддерживаемых парсером HTTP-методов.
http.STATUS_CODES
Коллекция всех стандартных кодов состояния HTTP-ответа и краткого описания каждого из них. Например, http.STATUS_CODES[404] === 'Not
Found'.
http.createServer([requestListener])
-
requestListener<Function> -
Возвращает: <http.Server>
Возвращает новый экземпляр http.Server.
requestListener — функция, автоматически добавленная к событию 'request'.
http.get(options[, callback])
-
options<Объект> | <строка> | <URL> Принимает те жеoptionsчто иhttp.request(), сmethodвсегда установленным вGET. Свойства, унаследованные от прототипа, игнорируются. -
callback<Функция> - Возвращает: <http.ClientRequest>
Поскольку большинство запросов являются GET-запросами без тел, Node.js предоставляет этот удобный метод. Единственное отличие между этим методом и http.request() заключается в том, что он устанавливает метод на GET и вызывает req.end() автоматически. Обратите внимание, что обработчик должен позаботиться о потребления данных ответа по причинам, изложенным в разделе http.ClientRequest.
callback вызывается с одним аргументом, который является экземпляром http.IncomingMessage
Пример извлечения JSON:
http.get('http://nodejs.org/dist/index.json', (res) => {
const { statusCode } = res;
const contentType = res.headers['content-type'];
let error;
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}`);
});
http.globalAgent
Глобальный экземпляр Agent , который используется по умолчанию для всех HTTP-клиентских запросов.
http.maxHeaderSize
Только для чтения свойство, определяющее максимальный разрешенный размер HTTP-заголовков в байтах. По умолчанию 8 КБ. Настраивается с помощью параметра командной строки --max-http-header-size.
http.request(options[, callback])
-
options<Объект> | <строка> | <URL>-
protocol<строка> Протокол для использования. По умолчанию:http:. -
host<строка> Имя домена или IP-адрес сервера, которому требуется отправить запрос. По умолчанию:localhost. -
hostname<строка> Псевдоним дляhost. Для поддержкиurl.parse(), рекомендуется использоватьhostnameвместоhost. -
family<число> Семейство IP-адресов для использования при разрешенииhostиhostname. Допустимые значения4или6. Если не указано, будут использоваться как IP v4, так и v6. -
port<число> Порт удаленного сервера. По умолчанию:80. -
localAddress<строка> Локальный интерфейс для привязки к сетевым соединениям. -
socketPath<строка> Unix Domain Socket (используйте один из host:port или socketPath). -
method<строка> Строка, определяющая метод HTTP-запроса. По умолчанию:'GET'. -
path<строка> Путь к запросу. Должен включать строку запроса, если она есть. Например,'/index.html?page=12'. Исключение генерируется, когда путь запроса содержит недопустимые символы. В настоящее время отбрасываются только пробелы, но это может измениться в будущем. По умолчанию:'/'. -
headers<Объект> Объект, содержащий заголовки запроса. -
auth<строка> Базовая аутентификация, т.е.'user:password'для вычисления заголовка Authorization. -
agent<http.Agent> | <логическое значение> Управляет поведениемAgent. Возможные значения:-
undefined(по умолчанию): использоватьhttp.globalAgentдля этого хоста и порта. -
Agentобъект: явно использовать переданныйAgent. -
false: заставляет использовать новыйAgentс значениями по умолчанию.
-
-
createConnection<Функция> Функция, которая создаёт сокет/поток для использования в запросе, когда не используется опцияagent. Это можно использовать для избежания создания пользовательского классаAgentтолько для переопределения функции по умолчаниюcreateConnection. Подробнее см.agent.createConnection(). Любой потокDuplexявляется допустимым возвращаемым значением. -
timeout<число>: Число, определяющее тайм-аут сокета в миллисекундах. Это установит тайм-аут до подключения сокета.
-
-
callback<Функция> - Возвращает: <http.ClientRequest>
Node.js поддерживает несколько подключений на один сервер для выполнения HTTP-запросов. Эта функция позволяет прозрачно отправлять запросы.
options может быть объектом, строкой или объектом URL. Если options является строкой, она автоматически анализируется с помощью url.parse(). Если это объект URL, он автоматически преобразуется в обычный объект options.
Необязательный параметр callback будет добавлен в качестве одноразового обработчика для события 'response'.
http.request() возвращает экземпляр класса http.ClientRequest. Экземпляр ClientRequest является потоком для записи. Если необходимо загрузить файл с POST-запросом, запишите в объект ClientRequest.
Пример:
const postData = querystring.stringify({
'msg': 'Hello World!'
});
const options = {
hostname: 'www.google.com',
port: 80,
path: '/upload',
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'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' отключит кодировку по умолчанию chunked.
-
Отправка заголовка 'Expect' немедленно отправит заголовки запроса. Обычно при отправке 'Expect: 100-continue' следует установить тайм-аут и обработчик события
continue. Дополнительную информацию см. в RFC2616 Раздел 8.2.3. -
Отправка заголовка Authorization переопределит использование опции
authдля вычисления базовой аутентификации.
Пример с использованием URL в качестве options:
const { URL } = require('url');
const options = new URL('http://abc:xyz@example.com');
const req = http.request(options, (res) => {
// ...
});
При успешном запросе будут испускаться следующие события в указанном порядке:
socket-
response-
dataлюбое количество раз, на объектеres(dataвообще не будет испускаться, если тело ответа пустое, например, при большинстве перенаправлений) -
endна объектеres
-
close
В случае ошибки соединения будут испущены следующие события:
socketerrorclose
Если req.abort() вызван до успешного соединения, будут испущены следующие события в указанном порядке:
socket- (
req.abort()вызывается здесь) abortclose-
errorс ошибкой с сообщениемError: socket hang upи кодомECONNRESET
Если req.abort() вызывается после получения ответа, следующие события будут испускаться в следующем порядке:
socket-
response-
dataлюбое количество раз, на объектеres
-
- (
req.abort()вызывается здесь) abort-
close-
abortedна объектеres -
endна объектеres -
closeна объектеres
-
Обратите внимание, что установка параметра timeout или использование функции setTimeout не прервет запрос и не сделает ничего, кроме добавления события timeout.
© 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-v8.x/docs/api/http.html