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


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

    • protocol <string> 使用的协议。默认值: 'http:'
    • host <string> 请求发送至的服务器的域名或 IP 地址。默认值: 'localhost'
    • hostname <string> host 的别名。为了支持 url.parse(),如果同时指定 hosthostname,则使用 hostname
    • family <number> 当解析 hosthostname 时使用的 IP 地址族。有效值为 46。如果没有指定,则同时使用 IP v4 和 v6。
    • port <number> 远程服务器的端口。默认值: 80
    • localAddress <string> 为网络连接绑定的本地接口。
    • socketPath <string> Unix 域套接字。如果指定了 hostport 之一(它们指定了 TCP 套接字),则不能使用此选项。
    • method <string> 一个字符串,指定 HTTP 请求的方法。默认值: 'GET'
    • path <string> 请求的路径。应包括查询字符串(如果有)。例如 '/index.html?page=12'。当请求的路径包含非法的字符时,则抛出异常。目前只有空格被拒绝,但未来可能会有所变化。默认值: '/'
    • headers <Object> 包含请求头的对象。
    • auth <string> 基本的身份验证,即 'user:password',用于计算授权请求头。
    • agent <http.Agent> | <boolean> 控制 Agent 的行为。可能的值有:

      • undefined (默认): 对此主机和端口使用 http.globalAgent
      • Agent 对象: 显式地使用传入的 Agent
      • false: 使用新建的具有默认值的 Agent
    • createConnection <Function>agent 选项未被使用时,用来为请求生成套接字或流的函数。这可用于避免创建自定义的 Agent 类以覆盖默认的 createConnection 函数。详见 agent.createConnection()。任何双工流都是有效的返回值。
    • timeout <number>: 指定套接字超时的数值,以毫秒为单位。这会在套接字被连接之前设置超时。
    • setHost <boolean>: 指定是否自动添加 Host 请求头。默认值: true
  • callback <Function>
  • 返回: <http.ClientRequest>

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

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

如果同时指定了 urloptions,则对象会被合并,其中 options 属性优先。

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

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

const postData = querystring.stringify({
  'msg': '你好世界'
});

const options = {
  hostname: 'nodejs.cn',
  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(`状态码: ${res.statusCode}`);
  console.log(`响应头: ${JSON.stringify(res.headers)}`);
  res.setEncoding('utf8');
  res.on('data', (chunk) => {
    console.log(`响应主体: ${chunk}`);
  });
  res.on('end', () => {
    console.log('响应中已无数据');
  });
});

req.on('error', (e) => {
  console.error(`请求遇到问题: ${e.message}`);
});

// 将数据写入请求主体。
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' 事件的监听器。详见 RFC2616 的第 8.2.3 节。

  • 发送授权请求头会使用 auth 选项覆盖以计算基本的身份验证。

使用 URL 作为 options 的示例:

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

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

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

  • 'socket' 事件
  • 'response' 事件

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

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

  • 'socket' 事件
  • 'error' 事件
  • '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' 事件
  • 'close' 事件
  • res 对象上的 'end' 事件
  • res 对象上的 'close' 事件

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

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

    • protocol <string> Protocol to use. Default: 'http:'.
    • host <string> A domain name or IP address of the server to issue the request to. Default: 'localhost'.
    • hostname <string> Alias for host. To support url.parse(), hostname will be used if both host and hostname are specified.
    • family <number> IP address family to use when resolving host or hostname. Valid values are 4 or 6. When unspecified, both IP v4 and v6 will be used.
    • port <number> Port of remote server. Default: 80.
    • localAddress <string> Local interface to bind for network connections.
    • socketPath <string> Unix Domain Socket (cannot be used if one of host or port is specified, those specify a TCP Socket).
    • method <string> A string specifying the HTTP request method. Default: 'GET'.
    • path <string> Request path. Should include query string if any. E.G. '/index.html?page=12'. An exception is thrown when the request path contains illegal characters. Currently, only spaces are rejected but that may change in the future. Default: '/'.
    • headers <Object> An object containing request headers.
    • auth <string> Basic authentication i.e. 'user:password' to compute an Authorization header.
    • agent <http.Agent> | <boolean> Controls Agent behavior. Possible values:

      • undefined (default): use http.globalAgent for this host and port.
      • Agent object: explicitly use the passed in Agent.
      • false: causes a new Agent with default values to be used.
    • createConnection <Function> A function that produces a socket/stream to use for the request when the agent option is not used. This can be used to avoid creating a custom Agent class just to override the default createConnection function. See agent.createConnection() for more details. Any Duplex stream is a valid return value.
    • timeout <number>: A number specifying the socket timeout in milliseconds. This will set the timeout before the socket is connected.
    • setHost <boolean>: Specifies whether or not to automatically add the Host header. Defaults to true.
  • callback <Function>
  • Returns: <http.ClientRequest>

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

url can be a string or a URL object. If url is a string, it is automatically parsed with url.parse(). If it is a URL object, it will be automatically converted to an ordinary options object.

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

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

http.request() returns an instance of the http.ClientRequest class. The ClientRequest instance is a writable stream. If one needs to upload a file with a POST request, then write to the ClientRequest object.

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

Note that 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.

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.

  • Sending a 'Connection: keep-alive' will notify Node.js that the connection to the server should be persisted until the next request.

  • Sending a 'Content-Length' header will disable the default chunked encoding.

  • Sending an 'Expect' header will immediately send the request headers. Usually, when sending 'Expect: 100-continue', both a timeout and a listener for the 'continue' event should be set. See RFC2616 Section 8.2.3 for more information.

  • Sending an Authorization header will override using the auth option to compute basic authentication.

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' any number of times, on the res object ('data' will not be emitted at all if the response body is empty, for instance, in most redirects)
    • 'end' on the res object
  • 'close'

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

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

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

  • 'socket'
  • (req.abort() called here)
  • 'abort'
  • 'error' with an error with message 'Error: socket hang up' and code 'ECONNRESET'
  • 'close'

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

  • 'socket'
  • 'response'

    • 'data' any number of times, on the res object
  • (req.abort() called here)
  • 'abort'
  • 'aborted' on the res object
  • 'close'
  • 'end' on the res object
  • 'close' on the res object

Note that setting the timeout option or using the setTimeout() function will not abort the request or do anything besides add a 'timeout' event.