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


  • url <string> | <URL>
  • options <Object>
    • agent <http.Agent> | <boolean> 控制 Agent 行为。可能的取值:
      • undefined(默认):对该主机和端口使用 http.globalAgent
      • Agent 对象:明确使用传入的 Agent
      • false:会使用具有默认值的新 Agent
    • auth <string> 基本身份验证('user:password'),用于计算 Authorization 头。
    • createConnection <Function> 一个函数,用于在未使用 agent 选项时生成用于请求的 socket/流。可以使用它来避免仅为了重写默认的 createConnection 函数而创建自定义 Agent 类。有关更多详细信息,请参见 agent.createConnection()。任何 Duplex 流都是有效的返回值。
    • defaultPort <number> 协议的默认端口。默认值: 如果使用 Agent,则为 agent.defaultPort,否则为 undefined
    • family <number> 在解析 hosthostname 时使用的 IP 地址类型。有效值为 46。如果未指定,将同时使用 IPv4 和 IPv6。
    • headers <Object> | <Array> 一个包含请求头的对象或字符串数组。数组的格式与 message.rawHeaders 相同。
    • 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 则使用,否则为 80
    • protocol <string> 使用的协议。默认值: 'http:'
    • setDefaultHeaders <boolean>:指定是否自动添加默认头,如 ConnectionContent-LengthTransfer-EncodingHost。如果设置为 false,则所有必要的头都必须手动添加。默认值为 true
    • setHost <boolean>:指定是否自动添加 Host 头。如果提供,则会覆盖 setDefaultHeaders。默认值为 true
    • signal <AbortSignal>:一个可以用于中止正在进行的请求的 AbortSignal。
    • socketPath <string> Unix 域套接字。如果指定了 hostport,则不能使用,因为它们指定的是 TCP 套接字。
    • timeout <number>:一个数字,指定套接字超时的毫秒数。这将设置套接字连接前的超时时间。
    • uniqueHeaders <Array> 一份只应发送一次的请求头列表。如果请求头的值是数组,数组中的条目将使用 ; 连接。
  • callback <Function>
  • 返回: <http.ClientRequest>

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

Node.js 为每个服务器维护多个连接以进行 HTTP 请求。此功能允许用户透明地发起请求。

【Node.js maintains several connections per server to make HTTP requests. This function allows one to transparently issue requests.】

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

如果同时指定了 urloptions,这些对象将会合并,其中 options 的属性优先。

【If both url and options are specified, the objects are merged, with the options properties taking precedence.】

可选的 callback 参数将作为 'response' 事件的单次监听器添加。

【The optional callback parameter will be added as a one-time listener for the 'response' event.】

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() 来表示请求的结束——即使没有数据写入请求体。

【In the example req.end() was called. With http.request() one must always call req.end() to signify the end of the request - even if there is no data being written to the request body.】

如果在请求过程中遇到任何错误(无论是 DNS 解析、TCP 层错误,还是实际的 HTTP 解析错误),都会在返回的请求对象上触发 'error' 事件。与所有 'error' 事件一样,如果没有注册监听器,该错误将会被抛出。

【If any error is encountered during the request (be that with DNS resolution, TCP level errors, or actual HTTP parse errors) an 'error' event is emitted on the returned request object. As with all 'error' events, if no listeners are registered the error will be thrown.】

有一些特殊的标头需要注意。

【There are a few special headers that should be noted.】

  • 发送“Connection: keep-alive”将通知 Node.js,连接服务器应保持直到下一次请求。
  • 发送 'Content-Length' 头将会禁用默认的分块传输编码。
  • 发送 'Expect' 头会立即发送请求头。通常,在发送 'Expect: 100-continue' 时,应同时设置超时和 'continue' 事件的监听器。有关更多信息,请参阅 RFC 2616 第 8.2.3 节。
  • 发送授权头将覆盖使用 auth 选项来计算基本身份验证。

使用 URL 作为 options 的示例:

【Example using a URL as options:】

const options = new URL('http://abc:xyz@example.com');

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

在一次成功的请求中,将按以下顺序触发以下事件:

【In a successful request, the following events will be emitted in the following order:】

  • 'socket'
  • 'response'
    • 'data' 可以在 res 对象上出现任意次数(如果响应体为空,例如在大多数重定向中,'data' 将根本不会被触发)
    • res 对象上的 'end'
  • 'close'

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

【In the case of a connection error, the following events will be emitted:】

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

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

【In the case of a premature connection close before the response is received, the following events will be emitted in the following order:】

  • 'socket'
  • 'error',错误信息为 'Error: socket hang up',错误代码为 'ECONNRESET'
  • 'close'

在响应接收后,如果连接过早关闭,将按以下顺序触发以下事件:

【In the case of a premature connection close after the response is received, the following events will be emitted in the following order:】

  • 'socket'
  • 'response'
    • 'data'res 对象上可以出现任意次数
  • (连接已关闭)
  • res 对象上的 'aborted'
  • 'close'
  • res 对象上的 'error',错误信息为 'Error: aborted',错误代码为 'ECONNRESET'
  • res 对象上的 'close'

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

【If req.destroy() is called before a socket is assigned, the following events will be emitted in the following order:】

  • (此处调用了 req.destroy()
  • 'error' 错误,其消息为 'Error: socket hang up',代码为 'ECONNRESET',或者是调用 req.destroy() 时产生的错误
  • 'close'

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

【If req.destroy() is called before the connection succeeds, the following events will be emitted in the following order:】

  • 'socket'
  • (此处调用了 req.destroy()
  • 'error' 错误,其消息为 'Error: socket hang up',代码为 'ECONNRESET',或者是调用 req.destroy() 时产生的错误
  • 'close'

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

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

  • 'socket'
  • 'response'
    • 'data'res 对象上可以出现任意次数
  • (此处调用了 req.destroy()
  • res 对象上的 'aborted'
  • 'close'
  • res 对象上的 'error' 错误,错误信息为 'Error: aborted',错误代码为 'ECONNRESET',或者是用于调用 req.destroy() 的错误
  • res 对象上的 'close'

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

【If req.abort() is called before a socket is assigned, the following events will be emitted in the following order:】

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

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

【If req.abort() is called before the connection succeeds, the following events will be emitted in the following order:】

  • 'socket'
  • (此处调用了 req.abort()
  • 'abort'
  • 'error',错误信息为 'Error: socket hang up',错误代码为 'ECONNRESET'
  • 'close'

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

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

  • 'socket'
  • 'response'
    • 'data'res 对象上可以出现任意次数
  • (此处调用了 req.abort()
  • 'abort'
  • res 对象上的 'aborted'
  • res 对象上的 'error',错误信息为 'Error: aborted',错误代码为 'ECONNRESET'
  • 'close'
  • res 对象上的 'close'

设置 timeout 选项或使用 setTimeout() 函数不会中止请求,也不会做其他任何事情,只会添加一个 'timeout' 事件。

【Setting the timeout option or using the setTimeout() function will not abort the request or do anything besides add a 'timeout' event.】

传递一个 AbortSignal 然后在对应的 AbortController 上调用 abort(),其行为将与对请求调用 .destroy() 相同。具体来说,将触发 'error' 事件,并伴随一条错误消息 'AbortError: The operation was aborted'、错误代码 'ABORT_ERR',以及(如果提供了的话)cause

【Passing an AbortSignal and then calling abort() on the corresponding AbortController will behave the same way as calling .destroy() on the request. Specifically, the 'error' event will be emitted with an error with the message 'AbortError: The operation was aborted', the code 'ABORT_ERR' and the cause, if one was provided.】