Node.js v13.2.0 Documentation


Table of Contents

HTTP#

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

Node.js中的HTTP接口旨在支持该协议的许多功能,这些功能传统上难以使用. 特别是大的,可能是块编码的消息. 该界面非常小心,永远不要缓冲整个请求或响应-用户能够流式传输数据.

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

{ 'content-length': '123',
  'content-type': 'text/plain',
  'connection': 'keep-alive',
  'host': 'mysite.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', 'mysite.com',
  'accepT', '*/*' ]

Class: http.Agent#

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

池连接为它们启用了TCP Keep-Alive,但是服务器仍可以关闭空闲连接,在这种情况下,它们将从池中删除,并且当对该主机和端口发出新的HTTP请求时将建立新连接. 服务器也可能拒绝允许通过同一连接的多个请求,在这种情况下,必须为每个请求重新建立连接,并且不能将其合并. Agent仍然会向该服务器发出请求,但是每个请求都会通过一个新的连接发生.

当客户端或服务器关闭连接时,会将其从池中删除. 池中任何未使用的套接字都将被取消引用,以免在没有未完成的请求时不让Node.js进程运行. (请参阅socket.unref() ).

优良作法是在不再使用Agent实例时destroy()实例,因为未使用的套接字会占用OS资源.

当套接字发出'close'事件或'agentRemove'事件时, '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 <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>每个主机允许的最大套接字数. 每个请求将使用一个新的套接字,直到达到最大值为止. 默认值: Infinity .
    • maxFreeSockets <number>在空闲状态下保持打开状态的最大套接字数. 仅当keepAlive设置为true时才相关. 默认值: 256
    • timeout <number>套接字超时(以毫秒为单位). 创建套接字时,这将设置超时.

还支持socket.connect()中的options .

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

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

const http = require('http');
const keepAliveAgent = new http.Agent({ keepAlive: true });
options.agent = keepAliveAgent;
http.request(options, onResponseCallback);

agent.createConnection(options[, callback])[src]#

产生用于HTTP请求的套接字/流.

默认情况下,此函数与net.createConnection()相同. 但是,如果需要更大的灵活性,定制代理可以覆盖此方法.

可以通过以下两种方式之一提供套接字/流:通过从此函数返回套接字/流,或将套接字/流传callback .

此方法保证返回的实例<net.Socket>类,的一个子类<stream.Duplex> ,除非用户指定的套接字比其他类型的<net.Socket> .

callback具有(err, stream)的签名.

agent.keepSocketAlive(socket)[src]#

socket与请求分离并且可以由Agent持久保存时调用. 默认行为是:

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

特定的Agent子类可以覆盖此方法. 如果此方法返回一个伪造的值,则套接字将被销毁,而不是持久保存以供下一个请求使用.

所述socket参数可以是一个实例<net.Socket> ,的一个子类<stream.Duplex> .

agent.reuseSocket(socket, request)[src]#

socket由于持久连接选项而在持久化后附加到request时调用. 默认行为是:

socket.ref();

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

所述socket参数可以是一个实例<net.Socket> ,的一个子类<stream.Duplex> .

agent.destroy()[src]#

销毁该代理当前正在使用的所有套接字.

通常没有必要这样做. 但是,如果使用启用了keepAlive的代理,则最好在不再使用该代理时明确关闭该代理. 否则,套接字可能会在服务器终止之前悬吊很长时间.

agent.freeSockets#

启用keepAlive时,此对象包含当前正在等待代理使用的套接字数组. 请勿修改.

agent.getName(options)[src]#

  • options <Object>一组用于提供名称生成信息的选项

    • host <string>向其发出请求的服务器的域名或IP地址
    • port <number>远程服务器的端口
    • localAddress <string>发出请求时绑定网络连接的本地接口
    • family <integer>如果不等于undefined则必须为4或6.
  • Returns: <string>

获取一组请求选项的唯一名称,以确定是否可以重用连接. 对于HTTP代理,这将返回host:port:localAddresshost:port:localAddress:family . 对于HTTPS代理,名称包括确定套接字可重用性的CA,证书,密码和其他特定于HTTPS / TLS的选项.

agent.maxFreeSockets#

默认设置为256.对于启用了keepAlive代理,这将设置在空闲状态下保持打开状态的最大套接字数.

agent.maxSockets#

默认情况下设置为Infinity . 确定代理可以为每个源打开多少个并发套接字. Origin是agent.getName()的返回值.

agent.requests#

一个对象,其中包含尚未分配给套接字的请求队列. 请勿修改.

agent.sockets#

包含代理当前正在使用的套接字数组的对象. 请勿修改.

Class: http.ClientRequest#

此对象在内部创建,并从http.request()返回. 它表示一个正在进行的请求,其标头已经排队. 使用setHeader(name, value)getHeader(name)removeHeader(name) API仍可setHeader(name, value)标头. 实际的标头将与第一个数据块一起发送,或者在调用request.end() .

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

'response'事件期间,可以将侦听器添加到响应对象中. 特别是听'data'事件.

如果未添加'response'处理程序,则响应将被完全丢弃. 但是,如果添加了'response'事件处理程序,则必须消耗响应对象中的数据,方法是:在发生'readable'事件时调用response.read() ,或者添加'data'处理程序,或者通过调用.resume()方法. 在使用完数据之前,不会触发'end'事件. 同样,在读取数据之前,它将消耗内存,最终可能导致"进程内存不足"错误.

request对象不同,如果响应过早关闭,则response对象不会发出'error'事件,而是发出'aborted'事件.

Node.js不会检查Content-Length和已发送的正文长度是否相等.

Event: 'abort'#

在客户端中止请求时发出. 仅在第一次调用abort()发出此事件.

Event: 'connect'#

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

此事件是保证将通过实例<net.Socket>类,一个子类<stream.Duplex> ,除非用户指定的套接字比其他类型的<net.Socket> .

一对客户机和服务器对,说明如何侦听'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 { port, hostname } = new URL(`http://${req.url}`);
  const srvSocket = net.connect(port || 80, 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,
    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();
    });
  });
});

Event: 'continue'#

服务器发送" 100继续" HTTP响应时发出,通常是因为请求包含"期望:100-继续". 这是客户端应发送请求正文的指令.

Event: 'information'#

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

const http = require('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'事件.

Event: 'response'#

在收到对此请求的响应时发出. 此事件仅发出一次.

Event: 'socket'#

此事件是保证将通过实例<net.Socket>类,一个子类<stream.Duplex> ,除非用户指定的套接字比其他类型的<net.Socket> .

Event: 'timeout'#

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

另请参见: request.setTimeout() .

Event: 'upgrade'#

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

此事件是保证将通过实例<net.Socket>类,一个子类<stream.Duplex> ,除非用户指定的套接字比其他类型的<net.Socket> .

一对客户机服务器,演示如何侦听'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,
    host: '127.0.0.1',
    headers: {
      'Connection': 'Upgrade',
      'Upgrade': 'websocket'
    }
  };

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

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

request.abort()#

将请求标记为正在中止. 调用此命令将导致响应中的剩余数据被丢弃,套接字被破坏.

request.aborted#

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

request.connection#

稳定性:0-不推荐使用. 使用request.socket .

See request.socket.

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

完成发送请求. 如果身体的任何部分未发送,它将冲洗它们到流中. 如果请求是分块的,这将发送终止的'0\r\n\r\n' .

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

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

request.finished#

如果已调用request.end()request.finished属性为true . 如果请求是通过http.get()启动的,则将自动调用request.end() http.get() .

request.flushHeaders()#

刷新请求标头.

出于效率原因,Node.js通常会缓冲请求标头,直到调用request.end()或写入请求数据的第一块为止. 然后,它尝试将请求标头和数据打包到单个TCP数据包中.

通常这是所希望的(它节省了TCP往返),但是直到第一个数据要等到很久以后才发送时才需要. request.flushHeaders()绕过优化并启动请求.

request.getHeader(name)#

读取请求的标头. 名称不区分大小写. 返回值的类型取决于提供给request.setHeader()的参数.

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

request.maxHeadersCount#

限制最大响应头数. 如果设置为0,将不应用限制.

request.path#

request.removeHeader(name)#

删除已经定义到headers对象中的header.

request.removeHeader('Content-Type');

request.reusedSocket#

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

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

const http = require('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

通过标记一个请求是否重用套接字,我们可以基于它进行自动错误重试.

const http = require('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');

or

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

request.setNoDelay([noDelay])#

将套接字分配给该请求并连接socket.setNoDelay()将调用socket.setNoDelay() .

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

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

request.setTimeout(timeout[, callback])#

将套接字分配给此请求并连接socket.setTimeout()将调用socket.setTimeout() .

request.socket#

对基础套接字的引用. 通常,用户将不希望访问此属性. 特别是,由于协议解析器如何附加到套接字,套接字将不会发出'readable'事件. 也可以通过request.connection访问socket .

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

此属性保证是实例<net.Socket>类,的一个子类<stream.Duplex> ,除非用户指定了其他的插座型<net.Socket> .

request.writableEnded#

在调用request.end()之后为true . 此属性不指示是否已刷新数据,而是为此用途request.writableFinished .

request.writableFinished#

如果在发出'finish'事件之前立即将所有数据刷新到基础系统,则为true .

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

发送身体的一块. 通过多次调用此方法,可以将请求主体发送到服务器-在这种情况下,建议在创建请求时使用['Transfer-Encoding', 'chunked']标头行.

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

callback参数是可选的,并且在刷新该数据块时将被调用,但仅在该块为非空时才被调用.

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

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

Class: http.Server#

Event: 'checkContinue'#

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

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

发出并处理此事件时,不会发出'request'事件.

Event: 'checkExpectation'#

每次接收到带有HTTP Expect标头的请求时发出,该请求的值不是100-continue . 如果未侦听此事件,则服务器将根据情况自动响应417 Expectation Failed .

发出并处理此事件时,不会发出'request'事件.

Event: 'clientError'#

如果客户端连接发出'error'事件,它将在此处转发. 此事件的侦听器负责关闭/销毁基础套接字. 例如,可能希望通过自定义HTTP响应更优雅地关闭套接字,而不是突然断开连接.

此事件是保证将通过实例<net.Socket>类,一个子类<stream.Duplex> ,除非用户指定的套接字比其他类型的<net.Socket> .

默认行为是尝试在发生HPE_HEADER_OVERFLOW错误的情况下,使用HPE_HEADER_OVERFLOW Bad Request'或HPE_HEADER_OVERFLOW Request Header Fields Too Large' HPE_HEADER_OVERFLOW . 如果套接字不可写,则会立即销毁.

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'事件时,没有requestresponse对象,因此,发送的所有HTTP响应(包括响应标头和有效负载)都必须直接写入socket对象. 必须注意确保响应是格式正确的HTTP响应消息.

errError一个实例,带有两个额外的列:

  • bytesParsed :Node.js可能已经正确解析的请求数据包的字节数;
  • rawPacket :当前请求的原始数据包.

Event: 'close'#

服务器关闭时发出.

Event: 'connect'#

每次客户端请求HTTP CONNECT方法时发出. 如果未侦听此事件,则请求CONNECT方法的客户端将关闭其连接.

此事件是保证将通过实例<net.Socket>类,一个子类<stream.Duplex> ,除非用户指定的套接字比其他类型的<net.Socket> .

发出此事件后,请求的套接字将没有'data'事件侦听器,这意味着将需要对其进行绑定以便处理在该套接字上发送给服务器的数据.

Event: 'connection'#

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

用户也可以显式发出此事件,以将连接注入HTTP服务器. 在这种情况下,任何Duplex流都可以通过.

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

此事件是保证将通过实例<net.Socket>类,一个子类<stream.Duplex> ,除非用户指定的套接字比其他类型的<net.Socket> .

Event: 'request'#

每次有请求时发出. 每个连接可能有多个请求(对于HTTP Keep-Alive连接而言).

Event: 'upgrade'#

每次客户端请求HTTP升级时发出. 侦听此事件是可选的,客户端无法坚持更改协议.

发出此事件后,请求的套接字将没有'data'事件侦听器,这意味着将需要对其进行绑定以便处理在该套接字上发送给服务器的数据.

此事件是保证将通过实例<net.Socket>类,一个子类<stream.Duplex> ,除非用户指定的套接字比其他类型的<net.Socket> .

server.close([callback])[src]#

阻止服务器接受新连接. 参见net.Server.close() .

server.headersTimeout#

限制解析器等待接收完整的HTTP标头的时间.

在不活动的情况下,将应用server.timeout定义的规则. 但是,如果报头的发送速度非常慢(默认情况下,每2分钟最多发送一个字节),则基于不活动的超时仍将使连接保持打开状态. 为了防止这种情况,每当头数据到达时,都要进行一次额外的检查,即自建立连接以来,没有超过server.headersTimeout毫秒. 如果检查失败,则会在服务器对象上发出'timeout'事件,并且(默认情况下)套接字被破坏. 有关如何自定义超时行为的更多信息,请参见server.timeout .

server.listen()[src]#

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

server.listening#

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

server.maxHeadersCount#

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

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

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

如果服务器对象上有一个'timeout'事件侦听器,则将使用超时套接字作为参数来调用它.

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

server.timeout#

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

假定套接字超时之前的闲置毫秒数.

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

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

server.keepAliveTimeout#

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

完成写入最后一个响应之后,在销毁套接字之前,服务器需要等待不活动的毫秒数,以等待其他传入数据. 如果服务器在触发保持活动超时之前收到新数据,它将重置常规的不活动超时,即server.timeout .

值为0将禁用传入连接上的保持活动超时行为. 值为0会使http服务器的行为类似于8.0.0之前的Node.js版本,后者没有保持活动超时.

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

Class: http.ServerResponse#

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

Event: 'close'#

表示基础连接已终止.

Event: '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 .

See response.socket.

response.cork()#

See writable.cork().

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

该方法向服务器发送信号,指示所有响应头和主体已发送. 该服务器应认为此消息已完成. 必须在每个响应上调用方法response.end() .

如果指定了data ,则其效果实际上类似于调用response.write(data, encoding)紧随其后的是response.end(callback) .

如果指定了callback ,则在响应流结束时将调用它.

response.finished#

如果已经调用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 . 这意味着obj.toString()典型的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.sendDate#

如果为true,则Date标头将自动生成并发送到响应中(如果标头中尚不存在). 默认为true.

只能将其禁用以进行测试; HTTP在响应中需要Date标头.

response.setHeader(name, value)#

为隐式标头设置单个标头值. 如果此标头已存在于待发送标头中,则其值将被替换. 在此处使用字符串数组发送具有相同名称的多个标头. 非字符串值将被存储而无需修改. 因此, response.getHeader()可能返回非字符串值. 但是,非字符串值将转换为用于网络传输的字符串.

response.setHeader('Content-Type', 'text/html');

or

response.setHeader('Set-Cookie', ['type=ninja', 'language=javascript']);

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

使用header.response.setHeader 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])#

将套接字的超时值设置为msecs . 如果提供了回调,则将其作为侦听器添加到响应对象上的'timeout'事件中.

如果没有在请求,响应或服务器中添加'timeout'侦听器,则套接字在超时时将被销毁. 如果将处理程序分配给请求,响应或服务器的'timeout'事件,则必须显式处理超时的套接字.

response.socket#

对基础套接字的引用. 通常,用户将不希望访问此属性. 特别是,由于协议解析器如何附加到套接字,套接字将不会发出'readable'事件. 在response.end() ,该属性为空. 也可以通过response.connection访问socket .

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

此属性保证是实例<net.Socket>类,的一个子类<stream.Duplex> ,除非用户指定了其他的插座型<net.Socket> .

response.statusCode#

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

response.statusCode = 404;

After response header was sent to the client, this property indicates the status code which was sent out.

response.statusMessage#

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

response.statusMessage = 'Not found';

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

response.uncork()#

See writable.uncork().

response.writableEnded#

在调用response.end()之后为true . 此属性不指示是否已刷新数据,为此使用response.writableFinished .

response.writableFinished#

如果在发出'finish'事件之前立即将所有数据刷新到基础系统,则为true .

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

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

这发送了响应主体的一部分. 可以多次调用此方法以提供身体的连续部分.

http模块中,当请求是HEAD请求时,将省略响应主体. 类似地, 204304响应必须不包含消息正文.

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

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

第一次调用response.write() ,它将把缓冲的头信息和主体的第一块发送给客户端. 第二次调用response.write() ,Node.js假定将流传输数据,并分别发送新数据. 也就是说,响应被缓冲到主体的第一块.

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

response.writeContinue()#

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

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

将响应标头发送到请求. 状态代码是3位HTTP状态代码,例如404 . 最后一个参数headers是响应头. 可以选择提供一个人类可读的statusMessage作为第二个参数.

返回对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() ,则将计算隐式/可变头,并调用此函数.

使用header.response.setHeader response.setHeader()设置标头后,它们将与传递给response.writeHead()任何标头合并,并优先传递给response.writeHead()的标头.

If this method is called and response.setHeader() has not been called, it will directly write the supplied header values onto the network channel without caching internally, and the response.getHeader() on the header will not yield the expected result. If progressive population of headers is desired with potential future retrieval and modification, use response.setHeader() instead.

// 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 .

response.writeProcessing()#

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

Class: http.IncomingMessage#

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

Event: 'aborted'#

当请求被中止时发出.

Event: 'close'#

表示基础连接已关闭.

message.aborted#

如果请求已中止,则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.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将被丢弃.
  • set-cookie始终是一个数组. 重复项将添加到阵列中.
  • 对于重复的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])#

Calls message.connection.setTimeout(msecs, callback).

message.socket#

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

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

此属性保证是实例<net.Socket>类,的一个子类<stream.Duplex> ,除非用户指定了其他的插座型<net.Socket> .

message.statusCode#

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

3位数的HTTP响应状态代码. EG 404 .

message.statusMessage#

Only valid for response obtained from http.ClientRequest.

HTTP响应状态消息(原因短语). EG OKInternal Server Error .

message.trailers#

请求/响应预告片对象. 仅在'end'事件中填充.

message.url#

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

请求URL字符串. 它仅包含实际HTTP请求中存在的URL. 如果请求是:

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([options][, requestListener])[src]#

返回http.Server的新实例.

requestListener是一个自动添加到'request'事件的函数.

http.get(options[, callback])[src]#

http.get(url[, options][, callback])[src]#

由于大多数请求都是没有主体的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标头的最大允许大小(以字节为单位). 默认为8KB. 可以使用--max-http-header-size CLI选项进行配置.

http.request(options[, callback])[src]#

http.request(url[, options][, callback])[src]#

  • url <string> | <URL>
  • options <Object>

    • agent <http.Agent> | <boolean>控制Agent行为. 可能的值:

      • undefined (默认):为此主机和端口使用http.globalAgent .
      • Agent对象:显式使用传入的Agent .
      • false :导致使用具有默认值的新Agent .
    • auth <string>基本身份验证,即'user:password'用于计算Authorization标头.
    • createConnection <Function>一个函数,当不使用agent选项时,该函数生成用于请求的套接字/流. 这可以用来避免创建自定义的Agent类,而只是重写默认的createConnection函数. 有关更多详细信息,请参见agent.createConnection() . 任何Duplex流都是有效的返回值.
    • defaultPort <数字>协议的默认端口. 默认值: agent.defaultPort如果使用了Agent ),否则为undefined .
    • family <number>解析hosthostname时要使用的IP地址家族. 有效值为46 . 未指定时,将同时使用IP v4和v6.
    • headers <Object>一个包含请求标头的对象.
    • host <字符串>向其发出请求的服务器的域名或IP地址. 默认值: 'localhost' .
    • hostname <string> host别名. 为了支持url.parse() hostname如果两个将被用于hosthostname指定.
    • localAddress <string>用于绑定网络连接的本地接口.
    • lookup <功能>自定义查找功能. 默认值: dns.lookup() .
    • method <string>一个字符串,指定HTTP请求方法. 默认值: 'GET' .
    • path <字符串>请求路径. 应包含查询字符串(如果有). EG '/index.html?page=12' . 当请求路径包含非法字符时,将引发异常. 目前,只有空格被拒绝,但将来可能会改变. 默认值: '/' .
    • port <number>远程服务器的端口. 默认值:如果设置,则为defaultPort ,否则为80 .
    • protocol <string>使用的协议. 默认值: 'http:' .
    • setHost <boolean> :指定是否自动添加Host标头. 默认为true .
    • socketPath <string> Unix域套接字(如果指定了hostport之一,则指定TCP套接字,则不能使用).
    • timeout <number> :一个数字,指定套接字超时(以毫秒为单位). 这将设置连接套接字之前的超时时间.
  • callback <Function>
  • Returns: <http.ClientRequest>

Node.js为每个服务器维护几个连接以发出HTTP请求. 此功能允许透明地发出请求.

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

如果同时指定了urloptions ,则将合并对象,并以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'事件一样,如果未注册任何侦听器,则将引发错误.

有一些特殊的标头应注意.

  • 发送"连接:保持活动状态"将通知Node.js,与服务器的连接应一直保持到下一个请求.

  • 发送" Content-Length"标头将禁用默认的分块编码.

  • 发送"期望"标头将立即发送请求标头. 通常,在发送"期望:100-继续"时,应同时设置超时和'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'

    • 'data'任意次数,接通res对象( 'data'不会在所有的发射,如果响应体是空的,例如,在大多数重定向)
    • res对象上的'end'
  • 'close'

如果出现连接错误,将发出以下事件:

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

如果在收到响应之前过早关闭了连接,则将按以下顺序发出以下事件:

  • 'socket'
  • 'error'并显示错误消息'Error: socket hang up'和代码'ECONNRESET'
  • 'close'

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

  • 'socket'
  • 'response'

    • res对象上多次'data'
  • (此处连接已关闭)
  • res对象'aborted'
  • 'close'
  • res对象上的'close'

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

  • 'socket'
  • req.abort()在这里调用)
  • 'abort'
  • 'error'并显示错误消息'Error: socket hang up'和代码'ECONNRESET'
  • 'close'

If req.abort() is called after the response is received, the following events will be emitted in the following order:

  • 'socket'
  • 'response'

    • res对象上多次'data'
  • req.abort()在这里调用)
  • 'abort'
  • res对象'aborted'
  • 'close'
  • res对象上的'close'

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

by  ICOPY.SITE