HTTP#

稳定性:2 - 稳定

源代码: lib/http.js

要使用 HTTP 服务器和客户端,必须 require('node:http')

Node.js 中的 HTTP 接口旨在支持协议的许多功能,而这些功能传统上难以使用。特别是,大块且可能经过块编码的消息。该接口小心地从不缓冲整个请求或响应,因此用户能够传输数据。

HTTP 消息头由类似这样的对象表示

{ "content-length": "123",
  "content-type": "text/plain",
  "connection": "keep-alive",
  "host": "example.com",
  "accept": "*/*" } 

键为小写。值不会被修改。

为了支持各种可能的 HTTP 应用程序,Node.js HTTP API 的级别非常低。它仅处理流处理和消息解析。它将消息解析为头和正文,但它不会解析实际的头或正文。

有关如何处理重复头的详细信息,请参见 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', '*/*' ] 

类:http.Agent#

Agent 负责管理 HTTP 客户端的连接持久性和重用。它维护给定主机和端口的待处理请求队列,为每个队列重用一个套接字连接,直到队列为空,此时套接字将被销毁或放入池中,以便再次用于对同一主机和端口的请求。是否销毁或放入池取决于 keepAlive 选项

已放入池的连接已为其启用 TCP 保持活动,但服务器仍可能关闭空闲连接,在这种情况下,它们将从池中移除,并且当针对该主机和端口发出新的 HTTP 请求时,将建立一个新连接。服务器还可能拒绝通过同一连接允许多个请求,在这种情况下,必须为每个请求重新建立连接,并且不能放入池中。Agent 仍会向该服务器发出请求,但每个请求都将在一个新连接上进行。

当连接被客户端或服务器关闭时,它将从池中移除。池中任何未使用的套接字都将解除引用,以便在没有未完成请求时不保持 Node.js 进程运行。(请参见 socket.unref())。

当不再使用 Agent 实例时,最好将其 destroy(),因为未使用的套接字会消耗操作系统资源。

当套接字发出 'close' 事件或 'agentRemove' 事件时,套接字将从代理中移除。当打算长时间保持一个 HTTP 请求打开而不将其保留在代理中时,可以执行类似以下操作

http.get(options, (res) => {
  // Do stuff
}).on('socket', (socket) => {
  socket.emit('agentRemove');
}); 

代理也可用于单个请求。通过向 http.get()http.request() 函数提供 {agent: false} 作为选项,将为客户端连接使用具有默认选项的一次性 Agent

代理:否:

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 <Object> 在代理上设置的可配置选项集。可以具有以下字段
    • keepAlive <boolean> 即使没有未完成的请求,也要保留套接字,以便可以在将来请求中使用它们,而无需重新建立 TCP 连接。不要与Connection标头的keep-alive值混淆。在使用代理时,总是会发送Connection: keep-alive标头,但以下情况除外:显式指定Connection标头,或者将keepAlivemaxSockets选项分别设置为falseInfinity,在这种情况下,将使用Connection: close默认:false
    • keepAliveMsecs <number> 在使用keepAlive选项时,指定 TCP Keep-Alive 数据包的初始延迟。当keepAlive选项为falseundefined时,将忽略此选项。默认: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> 套接字超时(以毫秒为单位)。这将在创建套接字时设置超时。

socket.connect() 中的 options 也受支持。

http.request() 使用的默认 http.globalAgent 已将所有这些值设置为其各自的默认值。

要配置其中任何一个,必须创建一个自定义 http.Agent 实例。

import { Agent, request } from 'node:http';
const keepAliveAgent = new Agent({ keepAlive: true });
options.agent = keepAliveAgent;
request(options, onResponseCallback);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> 以外的套接字类型,否则此方法保证返回 <net.Socket> 类的实例,它是 <stream.Duplex> 的子类。

callback 的签名为 (err, stream)

agent.keepSocketAlive(socket)#

socket 从请求中分离并且可以由 Agent 持久化时调用。默认行为是

socket.setKeepAlive(true, this.keepAliveMsecs);
socket.unref();
return true; 

此方法可以被特定的 Agent 子类覆盖。如果此方法返回假值,则套接字将被销毁,而不是持久化以供下次请求使用。

socket 参数可以是 <net.Socket> 的实例,它是 <stream.Duplex> 的子类。

agent.reuseSocket(socket, request)#

socket 附加到 request 后调用,原因是由于保持活动选项而持久化。默认行为是

socket.ref(); 

此方法可以被特定的 Agent 子类覆盖。

socket 参数可以是 <net.Socket> 的实例,它是 <stream.Duplex> 的子类。

agent.destroy()#

销毁当前由代理使用的任何套接字。

通常不需要执行此操作。但是,如果使用启用了 keepAlive 的代理,则最好在不再需要时明确关闭代理。否则,套接字可能会在服务器终止它们之前长时间保持打开状态。

agent.freeSockets#

一个对象,其中包含当 keepAlive 启用时代理当前正在等待使用的套接字数组。不要修改。

freeSockets 列表中的套接字将在 'timeout' 时自动销毁并从数组中删除。

agent.getName([options])#

  • options <Object> 提供用于生成名称的信息的一组选项
    • host <string> 要向其发出请求的服务器的域名或 IP 地址
    • port <number> 远程服务器的端口
    • localAddress <string> 在发出请求时为网络连接绑定的本地接口
    • family <integer> 如果不等于 undefined,则必须为 4 或 6。
  • 返回:<string>

为一组请求选项获取唯一名称,以确定是否可以重用连接。对于 HTTP 代理,这将返回 host:port:localAddresshost: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.request() 返回。它表示一个正在进行的请求,其标头已排队。标头仍可使用 setHeader(name, value)getHeader(name)removeHeader(name) API 进行修改。实际标头将与第一个数据块一起发送,或在调用 request.end() 时发送。

要获取响应,请为请求对象添加 'response' 的侦听器。当收到响应标头时,将从请求对象发出 'response'。使用一个参数执行 'response' 事件,该参数是 http.IncomingMessage 的一个实例。

'response' 事件期间,可以向响应对象添加侦听器;特别是侦听 'data' 事件。

如果没有添加 'response' 处理程序,那么响应将被完全丢弃。但是,如果添加了 'response' 事件处理程序,那么必须通过在每次出现 'readable' 事件时调用 response.read(),或通过添加 'data' 处理程序,或通过调用 .resume() 方法来使用响应对象中的数据。在使用数据之前,'end' 事件将不会触发。此外,在读取数据之前,它将消耗内存,最终可能导致“进程内存不足”错误。

为了向后兼容,只有在注册了'error'侦听器时,res才会发出'error'

设置Content-Length标头以限制响应正文大小。如果response.strictContentLength设置为true,则不匹配Content-Length标头值将导致抛出Error,由code: 'ERR_HTTP_CONTENT_LENGTH_MISMATCH'标识。

Content-Length值应以字节为单位,而不是字符。使用Buffer.byteLength()确定正文的字节长度。

事件:'abort'#

稳定性:0 - 已弃用。改为侦听'close'事件。

当请求被客户端中止时发出。此事件仅在首次调用abort()时发出。

事件:'close'#

表示请求已完成,或其底层连接已过早终止(在响应完成之前)。

事件:'connect'#

每当服务器使用CONNECT方法响应请求时发出。如果不侦听此事件,则接收CONNECT方法的客户端将关闭其连接。

此事件保证传递给<net.Socket>类的实例,它是<stream.Duplex>的子类,除非用户指定了除<net.Socket>之外的套接字类型。

演示如何侦听'connect'事件的客户端和服务器对

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

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

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

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

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

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

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

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

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

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

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

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

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

事件:'continue'#

当服务器发送'100 Continue' HTTP 响应时发出,通常是因为请求包含'Expect: 100-continue'。这是客户端应发送请求正文的指令。

事件:'finish'#

当请求已发送时发出。更具体地说,当响应标头和正文的最后一个片段已移交给操作系统以通过网络传输时,将发出此事件。这并不意味着服务器已经收到任何内容。

事件:'information'#

当服务器发送 1xx 中间响应(不包括 101 升级)时发出。此事件的侦听器将收到一个包含 HTTP 版本、状态代码、状态消息、键值对标头对象以及一个包含原始标头名称及其各自值的数组的对象。

import { request } from 'node:http';

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

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

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

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

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

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

由于 101 升级状态与传统的 HTTP 请求/响应链(例如 Web 套接字、就地 TLS 升级或 HTTP 2.0)中断,因此不会触发此事件。若要接收 101 升级通知,请改而侦听 'upgrade' 事件。

事件:'response'#

当对此请求收到响应时发出。此事件仅发出一次。

事件:'socket'#

此事件保证传递给<net.Socket>类的实例,它是<stream.Duplex>的子类,除非用户指定了除<net.Socket>之外的套接字类型。

事件:'timeout'#

当底层套接字因不活动而超时时发出。这仅通知套接字已处于空闲状态。必须手动销毁请求。

另请参阅:request.setTimeout()

事件:'upgrade'#

每次服务器以升级响应请求时都会发出。如果未侦听此事件且响应状态代码为 101 切换协议,则接收升级标头的客户端连接将关闭。

此事件保证传递给<net.Socket>类的实例,它是<stream.Duplex>的子类,除非用户指定了除<net.Socket>之外的套接字类型。

演示如何侦听 'upgrade' 事件的客户端服务器对。

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);
  });
});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()#

稳定性:0 - 已弃用:改为使用 request.destroy()

将请求标记为中止。调用此方法将导致响应中剩余的数据被丢弃,并且套接字被销毁。

request.aborted#

稳定性:0 - 已弃用。改为检查 request.destroyed

如果请求已中止,则 request.aborted 属性将为 true

request.connection#

稳定性:0 - 已弃用。使用 request.socket

请参阅 request.socket

request.cork()#

请参阅 writable.cork()

request.end([data[, encoding]][, callback])#

完成发送请求。如果正文的任何部分未发送,它会将它们刷新到流中。如果请求被分块,这将发送终止符 '0\r\n\r\n'

如果指定了 data,则相当于调用 request.write(data, encoding),后跟 request.end(callback)

如果指定了 callback,则在请求流完成时调用它。

request.destroy([error])#

  • error <Error> 可选,使用 'error' 事件发出的错误。
  • 返回:<this>

销毁请求。可以发出 'error' 事件,并发出 'close' 事件。调用此方法将导致响应中剩余的数据被丢弃,并且套接字被销毁。

有关更多详细信息,请参阅 writable.destroy()

request.destroyed#

在调用 request.destroy() 后为 true

有关更多详细信息,请参阅 writable.destroyed

request.finished#

稳定性:0 - 已弃用。请使用 request.writableEnded

如果已调用 request.end(),则 request.finished 属性将为 true。如果通过 http.get() 发起请求,则会自动调用 request.end()

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[] 

request.getHeaderNames()#

返回一个包含当前传出头的唯一名称的数组。所有头名称都为小写。

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

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

request.getHeaders()#

返回当前传出头的浅拷贝。由于使用了浅拷贝,因此可以在不额外调用各种与头相关的 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'] } 

request.getRawHeaderNames()#

返回一个包含当前传出原始头的唯一名称的数组。返回的头名称带有其确切的大小写。

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

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

request.hasHeader(name)#

如果当前在传出标头中设置了由 name 标识的标头,则返回 true。标头名称匹配不区分大小写。

const hasContentType = request.hasHeader('content-type'); 

request.maxHeadersCount#

限制最大响应标头数。如果设置为 0,则不应用限制。

request.path#

request.method#

request.host#

request.protocol#

request.removeHeader(name)#

移除已定义到标头对象中的标头。

request.removeHeader('Content-Type'); 

request.reusedSocket#

  • <boolean> 请求是否通过重用套接字发送。

通过启用保持活动状态的代理发送请求时,基础套接字可能会被重用。但是,如果服务器在不幸的时间关闭连接,客户端可能会遇到“ECONNRESET”错误。

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 timeoutconst 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

通过标记请求是否复用套接字,我们可以根据它自动重试错误。

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

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

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

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

retriableRequest();

request.setHeader(name, value)#

为标头对象设置单个标头值。如果此标头已存在于待发送标头中,则其值将被替换。在此处使用字符串数组以使用相同名称发送多个标头。非字符串值将存储而不进行修改。因此,request.getHeader() 可能会返回非字符串值。但是,非字符串值将被转换为字符串以进行网络传输。

request.setHeader('Content-Type', 'application/json'); 

或者

request.setHeader('Cookie', ['type=ninja', 'language=javascript']); 

如果值是字符串,则当它包含 latin1 编码之外的字符时,将引发异常。

如果您需要在值中传递 UTF-8 字符,请使用 RFC 8187 标准对值进行编码。

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

request.setNoDelay([noDelay])#

一旦套接字被分配给此请求并连接,将调用 socket.setNoDelay()

request.setSocketKeepAlive([enable][, initialDelay])#

一旦套接字被分配给此请求并连接,将调用 socket.setKeepAlive()

request.setTimeout(timeout[, callback])#

一旦套接字被分配给此请求并已连接,socket.setTimeout() 将被调用。

request.socket#

对底层套接字的引用。通常用户不会希望访问此属性。特别是,套接字不会发出 'readable' 事件,因为协议解析器是如何附加到套接字的。

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

此属性保证是 <net.Socket> 类的实例,它是 <stream.Duplex> 的子类,除非用户指定了 <net.Socket> 以外的套接字类型。

request.uncork()#

参见 writable.uncork()

request.writableEnded#

在调用 request.end() 之后为 true。此属性不表示数据是否已刷新,为此请改用 request.writableFinished

request.writableFinished#

如果所有数据已刷新到底层系统,则为 true,立即在发出 'finish' 事件之前。

request.write(chunk[, encoding][, callback])#

发送正文块。此方法可以多次调用。如果没有设置 Content-Length,数据将自动编码为 HTTP 分块传输编码,以便服务器知道数据何时结束。将添加 Transfer-Encoding: chunked 标头。调用 request.end() 是完成发送请求所必需的。

encoding 参数是可选的,仅在 chunk 为字符串时适用。默认为 'utf8'

callback 参数是可选的,当刷新此数据块时将调用它,但仅当该块非空时。

如果整个数据已成功刷新到内核缓冲区,则返回 true。如果全部或部分数据已排队在用户内存中,则返回 false。当缓冲区再次可用时,将发出 'drain'

当使用空字符串或缓冲区调用 write 函数时,它不执行任何操作并等待更多输入。

类:http.Server#

事件:'checkContinue'#

每当收到带有 HTTP Expect: 100-continue 的请求时发出。如果未侦听此事件,服务器将自动根据需要响应 100 Continue

处理此事件涉及调用 response.writeContinue()(如果客户端应继续发送请求主体),或生成适当的 HTTP 响应(例如 400 Bad Request)(如果客户端不应继续发送请求主体)。

发出并处理此事件后,将不会发出 'request' 事件。

事件:'checkExpectation'#

每当收到带有 HTTP Expect 标头的请求时发出,其中值不是 100-continue。如果未侦听此事件,服务器将自动根据需要响应 417 Expectation Failed

发出并处理此事件后,将不会发出 'request' 事件。

事件:'clientError'#

如果客户端连接发出 'error' 事件,则会转发到此处。此事件的侦听器负责关闭/销毁底层套接字。例如,人们可能希望使用自定义 HTTP 响应更优雅地关闭套接字,而不是突然断开连接。在侦听器结束之前,必须关闭或销毁套接字。

此事件保证传递给<net.Socket>类的实例,它是<stream.Duplex>的子类,除非用户指定了除<net.Socket>之外的套接字类型。

默认行为是尝试使用 HTTP '400 Bad Request' 关闭套接字,或者在出现 HPE_HEADER_OVERFLOW 错误时使用 HTTP '431 Request Header Fields Too Large'。如果套接字不可写或已发送当前附加 http.ServerResponse 的标头,则会立即销毁该套接字。

socket 是错误源自的 net.Socket 对象。

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);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' 事件发生时,没有 requestresponse 对象,因此发送的任何 HTTP 响应(包括响应标头和有效负载)必须直接写入 socket 对象。必须小心以确保响应是格式正确的 HTTP 响应消息。

errError 的一个实例,具有两列额外信息

  • 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');
}); 

事件:'close'#

服务器关闭时发出。

事件:'connect'#

每次客户端请求 HTTP CONNECT 方法时都会发出。如果未监听此事件,则请求 CONNECT 方法的客户端的连接将被关闭。

此事件保证传递给<net.Socket>类的实例,它是<stream.Duplex>的子类,除非用户指定了除<net.Socket>之外的套接字类型。

发出此事件后,请求的套接字将没有 'data' 事件监听器,这意味着需要绑定该套接字才能处理发送到该套接字上的数据。

事件:'connection'#

建立新的 TCP 流时会发出此事件。socket 通常是 net.Socket 类型的对象。通常,用户不希望访问此事件。特别是,由于协议解析器如何附加到套接字,因此套接字不会发出 'readable' 事件。还可以在 request.socket 中访问 socket

此事件还可以由用户显式发出,以将连接注入到 HTTP 服务器中。在这种情况下,可以传递任何 Duplex 流。

如果在此处调用 socket.setTimeout(),则当套接字提供服务请求时,超时将被替换为 server.keepAliveTimeout(如果 server.keepAliveTimeout 非零)。

此事件保证传递给<net.Socket>类的实例,它是<stream.Duplex>的子类,除非用户指定了除<net.Socket>之外的套接字类型。

事件:'dropRequest'#

当套接字上的请求数达到 server.maxRequestsPerSocket 的阈值时,服务器将放弃新的请求并发出 'dropRequest' 事件,然后向客户端发送 503

事件:'request'#

每次有请求时都会发出。每个连接可能有多个请求(在 HTTP 保持活动连接的情况下)。

事件:'upgrade'#

每次客户端请求 HTTP 升级时都会发出。监听此事件是可选的,并且客户端不能坚持协议更改。

发出此事件后,请求的套接字将没有 'data' 事件监听器,这意味着需要绑定该套接字才能处理发送到该套接字上的数据。

此事件保证传递给<net.Socket>类的实例,它是<stream.Duplex>的子类,除非用户指定了除<net.Socket>之外的套接字类型。

server.close([callback])#

停止服务器接受新连接,并关闭连接到此服务器且未发送请求或正在等待响应的所有连接。请参阅 net.Server.close()

server.closeAllConnections()#

关闭连接到此服务器的所有连接。

server.closeIdleConnections()#

关闭连接到此服务器且未发送请求或正在等待响应的所有连接。

server.headersTimeout#

限制解析器接收完整 HTTP 头所需等待的时间。

如果超时,服务器会响应状态 408,而不将请求转发到请求侦听器,然后关闭连接。

必须将其设置为非零值(例如 120 秒)以防范潜在的拒绝服务攻击,以防服务器在前面没有部署反向代理的情况下部署。

server.listen()#

启动 HTTP 服务器以侦听连接。此方法与 server.listen()net.Server 相同。

server.listening#

  • <boolean> 指示服务器是否正在侦听连接。

server.maxHeadersCount#

限制最大传入头计数。如果设置为 0,则不应用限制。

server.requestTimeout#

设置从客户端接收整个请求的超时值(以毫秒为单位)。

如果超时,服务器会响应状态 408,而不将请求转发到请求侦听器,然后关闭连接。

必须将其设置为非零值(例如 120 秒)以防范潜在的拒绝服务攻击,以防服务器在前面没有部署反向代理的情况下部署。

server.setTimeout([msecs][, callback])#

设置套接字的超时值,并在发生超时时在服务器对象上发出一个 'timeout' 事件,并将套接字作为参数传递。

如果服务器对象上有一个 'timeout' 事件侦听器,那么它将以超时套接字作为参数被调用。

默认情况下,服务器不会使套接字超时。但是,如果将回调分配给服务器的 'timeout' 事件,则必须显式处理超时。

server.maxRequestsPerSocket#

  • <number> 每个套接字的请求数。默认值:0(无限制)

套接字在关闭保持活动连接之前可以处理的最大请求数。

0 的值将禁用限制。

达到限制时,它将把 Connection 标头值设置为 close,但不会实际关闭连接,在达到限制后发送的后续请求将收到 503 服务不可用 作为响应。

server.timeout#

  • <number> 超时时间(以毫秒为单位)。默认值:0(无超时)

套接字被认为已超时的非活动时间(以毫秒为单位)。

0 的值将禁用传入连接的超时行为。

套接字超时逻辑在连接时设置,因此更改此值仅影响与服务器的新连接,而不影响任何现有连接。

server.keepAliveTimeout#

  • <number> 以毫秒为单位的超时时间。默认值:5000(5 秒)。

在服务器完成写入上一个响应后,等待接收更多传入数据的毫秒数,在套接字被销毁之前。如果服务器在 keep-alive 超时触发之前收到新数据,它将重置常规非活动超时,即 server.timeout

值为 0 将禁用传入连接上的 keep-alive 超时行为。值为 0 使 http 服务器的行为类似于 8.0.0 之前的 Node.js 版本,该版本没有 keep-alive 超时。

套接字超时逻辑在连接时设置,因此更改此值仅影响与服务器的新连接,而不影响任何现有连接。

server[Symbol.asyncDispose]()#

稳定性:1 - 实验性

调用 server.close() 并返回一个在服务器关闭后实现的 Promise。

类:http.ServerResponse#

此对象由 HTTP 服务器在内部创建,而不是由用户创建。它作为 'request' 事件的第二个参数传递。

事件:'close'#

表示响应已完成,或其底层连接在响应完成之前被过早终止。

事件:'finish'#

在响应已发送时发出。更具体地说,当响应头和正文的最后一个片段已移交给操作系统以通过网络传输时,会发出此事件。它并不意味着客户端已经收到任何内容。

response.addTrailers(headers)#

此方法将 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#

稳定性:0 - 已弃用。使用 response.socket

参见 response.socket

response.cork()#

请参阅 writable.cork()

response.end([data[, encoding]][, callback])#

此方法向服务器发出信号,表示所有响应头和正文已发送;服务器应将此消息视为已完成。必须对每个响应调用 response.end() 方法。

如果指定了 data,则其效果类似于依次调用 response.write(data, encoding)response.end(callback)

如果指定了 callback,则将在响应流完成后调用它。

response.finished#

稳定性:0 - 已弃用。使用 response.writableEnded

如果已调用 response.end(),则 response.finished 属性将为 true

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[] 

response.getHeaderNames()#

返回一个包含当前传出头的唯一名称的数组。所有头名称都为小写。

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

const headerNames = response.getHeaderNames();
// headerNames === ['foo', 'set-cookie'] 

response.getHeaders()#

返回当前传出头的浅拷贝。由于使用了浅拷贝,因此可以在不额外调用各种与头相关的 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。标头名称匹配不区分大小写。

const hasContentType = response.hasHeader('content-type'); 

response.headersSent#

布尔值(只读)。如果已发送标头,则为 True,否则为 False。

response.removeHeader(name)#

移除已排队进行隐式发送的标头。

response.removeHeader('Content-Encoding'); 

response.req#

对原始 HTTP request 对象的引用。

response.sendDate#

如果标头中尚未存在,则在为 True 时自动生成 Date 标头并在响应中发送。默认为 True。

仅应在测试时禁用此项;HTTP 要求在响应中使用 Date 标头。

response.setHeader(name, value)#

返回响应对象。

为隐式标头设置单个标头值。如果此标头已存在于待发送标头中,则其值将被替换。在此处使用字符串数组可发送具有相同名称的多个标头。非字符串值将存储而不进行修改。因此,response.getHeader() 可能会返回非字符串值。但是,非字符串值将转换为字符串以进行网络传输。将相同的响应对象返回给调用者,以启用调用链接。

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.writeHead() 方法且尚未调用此方法,则它将直接将提供的标头值写入网络通道而不进行内部缓存,并且标头上的 response.getHeader() 不会产生预期的结果。如果需要对标头进行渐进填充,并可能在将来进行检索和修改,请使用 response.setHeader() 而不是 response.writeHead()

response.setTimeout(msecs[, callback])#

将 Socket 的超时值设置为 msecs。如果提供了回调,则将其添加为响应对象上 'timeout' 事件的侦听器。

如果未向请求、响应或服务器添加 'timeout' 侦听器,则在超时时销毁套接字。如果向请求、响应或服务器的 'timeout' 事件分配了处理程序,则必须显式处理超时套接字。

response.socket#

对底层套接字的引用。通常,用户不会希望访问此属性。特别是,由于协议解析器附加到套接字的方式,套接字不会发出 'readable' 事件。在 response.end() 之后,该属性将变为 null。

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);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#

在使用隐式标头(不显式调用 response.writeHead())时,此属性控制在刷新标头时将发送到客户端的状态代码。

response.statusCode = 404; 

在将响应标头发送到客户端后,此属性指示已发送的状态代码。

response.statusMessage#

在使用隐式标头(不显式调用 response.writeHead())时,此属性控制在刷新标头时将发送到客户端的状态消息。如果将其保留为 undefined,则将使用状态代码的标准消息。

response.statusMessage = 'Not found'; 

在将响应标头发送到客户端后,此属性指示已发送的状态消息。

response.strictContentLength#

如果设置为 true,Node.js 将检查 Content-Length 标头值和正文大小(以字节为单位)是否相等。不匹配 Content-Length 标头值将导致抛出 Error,由 code: 'ERR_HTTP_CONTENT_LENGTH_MISMATCH' 标识。

response.uncork()#

参见 writable.uncork()

response.writableEnded#

在调用 response.end() 后为 true。此属性不表示数据是否已刷新,为此,请改用 response.writableFinished

response.writableFinished#

如果所有数据已刷新到底层系统,则为 true,立即在发出 'finish' 事件之前。

response.write(chunk[, encoding][, callback])#

如果调用此方法,并且尚未调用 response.writeHead(),它将切换到隐式标头模式并刷新隐式标头。

这会发送响应正文的一部分。此方法可以多次调用以提供正文的连续部分。

当请求方法或响应状态不支持内容时,不允许写入正文。如果尝试对 HEAD 请求或作为 204304 响应的一部分写入正文,则会抛出代码为 ERR_HTTP_BODY_NOT_ALLOWED 的同步 Error

chunk 可以是字符串或缓冲区。如果 chunk 是字符串,则第二个参数指定如何将其编码为字节流。当刷新此数据块时,将调用 callback

这是原始 HTTP 正文,与可能使用的更高级的多部分正文编码无关。

首次调用 response.write() 时,它会将缓冲的标头信息和正文的第一部分发送给客户端。第二次调用 response.write() 时,Node.js 假设数据将被流式传输,并单独发送新数据。也就是说,响应被缓冲到正文的第一部分。

如果整个数据已成功刷新到内核缓冲区,则返回 true。如果全部或部分数据已排队在用户内存中,则返回 false。当缓冲区再次可用时,将发出 'drain'

response.writeContinue()#

向客户端发送 HTTP/1.1 100 Continue 消息,表示应发送请求正文。请参阅 Server 上的 'checkContinue' 事件。

response.writeEarlyHints(hints[, callback])#

向客户端发送一个 HTTP/1.1 103 早期提示消息,其中包含一个 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); 

response.writeHead(statusCode[, statusMessage][, headers])#

向请求发送响应标头。状态代码是一个 3 位数的 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); 

此方法只能在消息上调用一次,并且必须在调用 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');
}); 

Content-Length 以字节为单位读取,而不是以字符为单位。使用 Buffer.byteLength() 来确定正文的长度(以字节为单位)。Node.js 将检查 Content-Length 和已传输正文的长度是否相等。

尝试设置包含无效字符的标头字段名称或值将导致抛出 [Error][]。

response.writeProcessing()#

向客户端发送 HTTP/1.1 102 处理消息,表示应发送请求正文。

类:http.IncomingMessage#

IncomingMessage 对象由 http.Serverhttp.ClientRequest 创建,并分别作为 'request''response' 事件的第一个参数传递。它可用于访问响应状态、标头和数据。

不同于其 socket 值(它是 <stream.Duplex> 的子类),IncomingMessage 本身扩展 <stream.Readable>,并单独创建以解析和发出传入的 HTTP 标头和有效负载,因为在保持活动的情况下,底层套接字可能会被多次重用。

事件:'aborted'#

稳定性:0 - 已弃用。请改用侦听 'close' 事件。

请求中止时发出。

事件:'close'#

请求完成时发出。

message.aborted#

稳定性:0 - 已弃用。从 <stream.Readable> 中检查 message.destroyed

如果请求已中止,则 message.aborted 属性将为 true

message.complete#

如果已收到并成功解析完整的 HTTP 消息,则 message.complete 属性将为 true

此属性特别有用,可用于确定在连接终止之前客户端或服务器是否完全传输了消息

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.connection#

稳定性:0 - 已弃用。使用 message.socket

message.socket 的别名。

message.destroy([error])#

在接收 IncomingMessage 的套接字上调用 destroy()。如果提供了 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); 

原始标头中的重复项将根据标头名称采用以下方式进行处理

  • ageauthorizationcontent-lengthcontent-typeetagexpiresfromhostif-modified-sinceif-unmodified-sincelast-modifiedlocationmax-forwardsproxy-authorizationrefererretry-afterserveruser-agent 的重复项将被丢弃。要允许组合上面列出的标头的重复值,请在 http.request()http.createServer() 中使用 joinDuplicateHeaders 选项。有关更多信息,请参阅 RFC 9110 第 5.3 节。
  • 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); 

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])#

调用 message.socket.setTimeout(msecs, callback)

message.socket#

与连接关联的 net.Socket 对象。

在 HTTPS 支持下,使用 request.socket.getPeerCertificate() 获取客户端的身份验证详细信息。

此属性保证是 <net.Socket> 类的实例,它是 <stream.Duplex> 的子类,除非用户指定了 <net.Socket> 以外的套接字类型或在内部将其置为 null。

message.statusCode#

仅对从 http.ClientRequest 获得的响应有效。

3 位 HTTP 响应状态代码。例如:404

message.statusMessage#

仅对从 http.ClientRequest 获得的响应有效。

HTTP 响应状态消息(原因短语)。例如:OKInternal Server Error

message.trailers#

请求/响应尾部对象。仅在 'end' 事件中填充。

message.trailersDistinct#

类似于 message.trailers,但没有联接逻辑,即使仅接收一次标头,值也始终是字符串数组。仅在 'end' 事件中填充。

message.url#

仅对从 http.Server 获取的请求有效。

请求 URL 字符串。这仅包含实际 HTTP 请求中存在的 URL。使用以下请求

GET /status?name=ryan HTTP/1.1
Accept: text/plain 

将 URL 解析为其组成部分

new URL(request.url, `http://${request.headers.host}`); 

request.url'/status?name=ryan'request.headers.host'localhost:3000'

$ node
> new URL(request.url, `http://${request.headers.host}`)
URL {
  href: 'http://localhost:3000/status?name=ryan',
  origin: 'http://localhost:3000',
  protocol: 'http:',
  username: '',
  password: '',
  host: 'localhost:3000',
  hostname: 'localhost',
  port: '3000',
  pathname: '/status',
  search: '?name=ryan',
  searchParams: URLSearchParams { 'name' => 'ryan' },
  hash: ''
} 

类:http.OutgoingMessage#

此类用作 http.ClientRequesthttp.ServerResponse 的父类。从 HTTP 事务参与者的角度来看,它是一个抽象的传出消息。

事件:'drain'#

当消息缓冲区再次释放时触发。

事件:'finish'#

当传输成功完成时触发。

事件:'prefinish'#

在调用 outgoingMessage.end() 之后触发。当触发该事件时,所有数据都已处理,但不一定已完全刷新。

outgoingMessage.addTrailers(headers)#

向消息添加 HTTP 尾部(标头,但位于消息末尾)。

仅当消息采用分块编码时,才会发出预告片。否则,将静默丢弃预告片。

HTTP 要求发送 Trailer 标头以发出预告片,其值中包含标头字段名称列表,例如:

message.writeHead(200, { 'Content-Type': 'text/plain',
                         'Trailer': 'Content-MD5' });
message.write(fileData);
message.addTrailers({ 'Content-MD5': '7895bf4b8828b55ceaf47747b4bca667' });
message.end(); 

尝试设置包含无效字符的标头字段名称或值将导致抛出 TypeError

outgoingMessage.appendHeader(name, value)#

将单个标头值追加到标头对象。

如果值是一个数组,这等效于多次调用此方法。

如果没有标头的先前值,这等效于调用 outgoingMessage.setHeader(name, value)

根据在创建客户端请求或服务器时 options.uniqueHeaders 的值,这最终会导致标头被发送多次或使用 ; 连接值一次发送。

outgoingMessage.connection#

稳定性:0 - 已弃用:改用 outgoingMessage.socket

outgoingMessage.socket 的别名。

outgoingMessage.cork()#

请参阅 writable.cork()

outgoingMessage.destroy([error])#

  • error <Error> 可选,一个带有 error 事件的错误
  • 返回:<this>

销毁消息。一旦套接字与消息关联并连接,该套接字也将被销毁。

outgoingMessage.end(chunk[, encoding][, callback])#

完成传出消息。如果正文的任何部分未发送,它将把它们刷新到底层系统。如果消息被分块,它将发送终止块 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)#

获取具有给定名称的 HTTP 头的值。如果未设置该头,则返回的值将为 undefined

outgoingMessage.getHeaderNames()#

返回一个数组,其中包含当前传出头的唯一名称。所有名称都为小写。

outgoingMessage.getHeaders()#

返回当前传出头的浅拷贝。由于使用浅拷贝,可以在不额外调用各种与头相关的 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'] } 

outgoingMessage.hasHeader(name)#

如果由 name 标识的标头当前在传出标头中设置,则返回 true。标头名称不区分大小写。

const hasContentType = outgoingMessage.hasHeader('content-type'); 

outgoingMessage.headersSent#

只读。如果标头已发送,则为 true,否则为 false

outgoingMessage.pipe()#

覆盖从旧版 Stream 类(http.OutgoingMessage 的父类)继承的 stream.pipe() 方法。

调用此方法将抛出 Error,因为 outgoingMessage 是一个只写流。

outgoingMessage.removeHeader(name)#

移除排队进行隐式发送的标头。

outgoingMessage.removeHeader('Content-Encoding'); 

outgoingMessage.setHeader(name, value)#

设置单个标头值。如果标头已存在于待发送标头中,则其值将被替换。使用字符串数组发送具有相同名称的多个标头。

outgoingMessage.setHeaders(headers)#

返回响应对象。

为隐式标头设置多个标头值。headers 必须是 HeadersMap 的实例,如果标头已存在于待发送标头中,则其值将被替换。

const headers = new Headers({ foo: 'bar' });
response.setHeaders(headers); 

或者

const headers = new Map([['foo', 'bar']]);
res.setHeaders(headers); 

如果已使用 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');
}); 

outgoingMessage.setTimeout(msesc[, callback])#

  • msesc <number>
  • callback <Function> 当超时发生时调用的可选函数。与绑定到 timeout 事件相同。
  • 返回:<this>

一旦套接字与消息关联并连接,socket.setTimeout() 将被调用,其中 msecs 作为第一个参数。

outgoingMessage.socket#

对底层套接字的引用。通常,用户不会希望访问此属性。

调用 outgoingMessage.end() 后,此属性将变为 null。

outgoingMessage.uncork()#

请参阅 writable.uncork()

outgoingMessage.writableCorked#

outgoingMessage.cork() 已被调用的次数。

outgoingMessage.writableEnded#

如果已调用 outgoingMessage.end(),则为 true。此属性并不表示数据已刷新。为此目的,请改用 message.writableFinished

outgoingMessage.writableFinished#

如果所有数据都已刷新到底层系统,则为 true

outgoingMessage.writableHighWaterMark#

如果已分配,则为底层套接字的 highWaterMark。否则,当 writable.write() 开始返回 false(16384)时的默认缓冲区级别。

outgoingMessage.writableLength#

缓冲字节数。

outgoingMessage.writableObjectMode#

始终为 false

outgoingMessage.write(chunk[, encoding][, callback])#

发送正文块。此方法可多次调用。

仅当 chunk 为字符串时,encoding 参数才相关。默认为 '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> 可选地覆盖所有 socketreadableHighWaterMarkwritableHighWaterMark。这会影响 IncomingMessageServerResponsehighWaterMark 属性。默认值:请参阅 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,它会在收到新的传入连接后立即在套接字上启用保持活动功能,类似于 [socket.setKeepAlive([enable][, initialDelay])][socket.setKeepAlive(enable, initialDelay)] 中所做的那样。默认值:false
    • keepAliveInitialDelay <number> 如果设置为正数,它将在空闲套接字上发送第一个保持活动探测之前设置初始延迟。默认值:0
    • keepAliveTimeout:服务器在完成上一次响应的编写后,等待接收更多传入数据的毫秒数,然后销毁套接字。有关更多信息,请参阅 server.keepAliveTimeout默认值:5000
    • maxHeaderSize <number> 可选择覆盖此服务器接收的请求的 --max-http-header-size 值,即以字节为单位的请求标头最大长度。默认值:16384(16 KiB)。
    • noDelay <boolean> 如果设置为 true,则在接收到新的传入连接后立即禁用使用 Nagle 算法。默认值:true
    • requestTimeout:设置从客户端接收整个请求的超时值(以毫秒为单位)。有关更多信息,请参阅 server.requestTimeout默认值:300000
    • requireHostHeader <boolean> 如果设置为 true,则强制服务器对任何缺少 Host 标头的 HTTP/1.1 请求消息以 400(错误请求)状态代码进行响应(如规范所要求)。默认值:true
    • ServerResponse <http.ServerResponse> 指定要使用的 ServerResponse 类。可用于扩展原始 ServerResponse默认值:ServerResponse
    • uniqueHeaders <Array> 应仅发送一次的响应标头列表。如果标头值是数组,则会使用 ; 将这些项连接起来。
  • requestListener <Function>

  • 返回:<http.Server>

返回 http.Server 的新实例。

requestListener 是自动添加到 'request' 事件的函数。

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);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);
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);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])#

由于大多数请求都是没有正文的 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); 

http.globalAgent#

Agent 的全局实例,用作所有 HTTP 客户端请求的默认值。

http.maxHeaderSize#

只读属性,指定 HTTP 头部的最大允许大小(以字节为单位)。默认为 16 KiB。可使用 --max-http-header-size CLI 选项进行配置。

可以通过传递 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')以计算授权头。
    • createConnection <Function> 当不使用 agent 选项时,用于生成套接字/流以供请求使用的函数。这可用于避免创建自定义 Agent 类,仅仅是为了覆盖默认的 createConnection 函数。有关更多详细信息,请参阅 agent.createConnection()。任何 Duplex 流都是有效的返回值。
    • defaultPort <number> 协议的默认端口。默认值:如果使用 Agent,则为 agent.defaultPort,否则为 undefined
    • family <number> 解析 hosthostname 时要使用的 IP 地址族。有效值为 46。未指定时,将同时使用 IP v4 和 v6。
    • headers <Object> 包含请求标头的对象。
    • hints <number> 可选的 dns.lookup() 提示
    • host <string> 要向其发出请求的服务器的域名或 IP 地址。默认值:'localhost'
    • hostname <string> host 的别名。为了支持 url.parse(),如果同时指定了 hosthostname,则将使用 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 KiB)。
    • method <string> 指定 HTTP 请求方法的字符串。默认值:'GET'
    • path <string> 请求路径。如果存在,应包含查询字符串。例如 '/index.html?page=12'。当请求路径包含非法字符时,将抛出异常。目前,仅拒绝空格,但将来可能会更改。默认值:'/'
    • port <number> 远程服务器的端口。默认值:如果设置了 defaultPort,则为 defaultPort,否则为 80
    • protocol <string> 要使用的协议。默认值:'http:'
    • setHost <boolean>:指定是否自动添加 Host 标头。默认为 true
    • signal <AbortSignal>:一个 AbortSignal,可用于中止正在进行的请求。
    • socketPath <string> Unix 域套接字。如果指定了 hostport 之一,则不能使用,因为它们指定了 TCP 套接字。
    • timeout <number>:指定套接字超时时间的数字(以毫秒为单位)。这将在套接字连接之前设置超时时间。
    • uniqueHeaders <Array> 仅应发送一次的请求标头列表。如果标头值是一个数组,则将使用 ; 连接这些项。
  • callback <Function>
  • 返回:<http.ClientRequest>

socket.connect() 中的 options 也受支持。

Node.js 为每个服务器维护多个连接以发出 HTTP 请求。此函数允许透明地发出请求。

url 可以是字符串或 URL 对象。如果 url 是一个字符串,则会使用 new URL() 自动解析它。如果它是一个 URL 对象,它将自动转换为一个普通的 options 对象。

如果同时指定了 urloptions,则这两个对象将合并,其中 options 属性优先。

可选的 callback 参数将作为 'response' 事件的一次性侦听器添加。

http.request() 返回 http.ClientRequest 类的实例。ClientRequest 实例是一个可写流。如果需要使用 POST 请求上传文件,则写入 ClientRequest 对象。

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();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' 事件的监听器。有关更多信息,请参阅 RFC 2616 第 8.2.3 节。

  • 发送 Authorization 标头会覆盖使用 auth 选项来计算基本身份验证。

使用 URL 作为 options 的示例

const options = new URL('http://abc:[email protected]');

const req = http.request(options, (res) => {
  // ...
}); 

在成功的请求中,将按以下顺序发出以下事件

  • 'socket'
  • 'response'
    • res 对象上多次发出 'data'(如果响应主体为空,则根本不会发出 'data',例如,在大多数重定向中)
    • res 对象上发出 'end'
  • 'close'

在连接错误的情况下,将发出以下事件

  • 'socket'
  • 'error'
  • 'close'

在收到响应之前过早关闭连接的情况下,将按以下顺序发出以下事件

  • 'socket'
  • 'error',其中包含消息为 'Error: socket hang up' 和代码为 'ECONNRESET' 的错误
  • 'close'

在收到响应之后过早关闭连接的情况下,将按以下顺序发出以下事件

  • 'socket'
  • 'response'
    • res 对象上多次发出 'data'
  • (此处关闭连接)
  • res 对象上发出 'aborted'
  • res 对象上发出 'error',其中包含消息为 'Error: aborted' 和代码为 'ECONNRESET' 的错误
  • 'close'
  • res 对象上发出 'close'

如果在分配套接字之前调用 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'
    • res 对象上多次发出 'data'
  • (此处调用 req.destroy()
  • res 对象上发出 'aborted'
  • res 对象上的 'error',错误消息为 'Error: aborted',错误代码为 'ECONNRESET',或者 req.destroy() 被调用的错误
  • 'close'
  • res 对象上发出 'close'

如果在分配套接字之前调用 req.abort(),将按以下顺序触发以下事件

  • (此处调用 req.abort())
  • 'abort'
  • 'close'

如果在连接成功之前调用 req.abort(),将按以下顺序触发以下事件

  • 'socket'
  • (此处调用 req.abort())
  • 'abort'
  • 'error',其中包含消息为 'Error: socket hang up' 和代码为 'ECONNRESET' 的错误
  • 'close'

如果在收到响应后调用 req.abort(),将按以下顺序触发以下事件

  • 'socket'
  • 'response'
    • res 对象上多次发出 'data'
  • (此处调用 req.abort())
  • 'abort'
  • res 对象上发出 'aborted'
  • res 对象上的 'error',错误消息为 'Error: aborted',错误代码为 'ECONNRESET'
  • 'close'
  • res 对象上发出 'close'

设置 timeout 选项或使用 setTimeout() 函数不会中止请求,也不会执行除添加 'timeout' 事件之外的任何操作。

传递一个 AbortSignal,然后在相应的 AbortController 上调用 abort(),其行为与在请求上调用 .destroy() 相同。具体来说,将触发 'error' 事件,其中错误消息为 'AbortError: The operation was aborted',错误代码为 'ABORT_ERR',如果提供了原因,则还包括原因。

http.validateHeaderName(name[, label])#

  • name <string>
  • label <string> 错误消息的标签。默认值: 'Header name'

对提供的 name 执行低级验证,该验证在调用 res.setHeader(name, value) 时执行。

将非法值作为 name 传递会导致抛出 TypeError,其标识为 code: 'ERR_INVALID_HTTP_TOKEN'

在将标头传递到 HTTP 请求或响应之前,不必使用此方法。HTTP 模块会自动验证此类标头。

示例

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 [""]'
}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)#

对在调用 res.setHeader(name, value) 时完成的提供的 value 执行低级别验证。

将非法值作为 value 传递会导致抛出 TypeError

  • 通过 code: 'ERR_HTTP_INVALID_HEADER_VALUE' 标识未定义的值错误。
  • 通过 code: 'ERR_INVALID_CHAR' 标识无效的值字符错误。

在将标头传递到 HTTP 请求或响应之前,不必使用此方法。HTTP 模块会自动验证此类标头。

示例

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"]'
}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)#

设置空闲 HTTP 解析器的最大数量。