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


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

    • protocol <string> 使用的协议。默认为 http:
    • host <string> 服务器的域名或 IP 地址。默认为 localhost
    • hostname <string> host 的别名。为了支持 url.parse()hostname 优先于 host
    • family <number> 解析 hosthostname 时使用的 IP 地址族。值可以是 46。如果没有指定,则同时使用 IP v4 和 v6。
    • port <number> 远程服务器的端口。默认为 80
    • localAddress <string> 网络连接绑定的本地接口。
    • socketPath <string> Unix 域 Socket。host:portsocketPath 二选一。
    • method <string> 请求的方法。默认为 'GET'
    • path <string> 请求的路径。可以包括查询字符串,如 '/index.html?page=12'。如果请求的路径中包含非法字符,则抛出异常。默认为 '/'
    • headers <Object> 请求头。
    • auth <string> 基本身份验证,如使用 'user:password' 计算 Authorization 请求头。
    • agent <http.Agent> | <boolean> 控制 Agent 的行为。可选的值有:

      • undefined (默认): 使用 http.globalAgent
      • Agent: 使用传入的 Agent
      • false: 新建一个使用默认配置的 Agent
    • createConnection <Function> 如果没有指定 agent,则可用该函数为请求创建 socket 或流。这可以避免只是为了重写默认的 createConnection 而创建自定义的 Agent。详见 agent.createConnection()
    • timeout <number>: socket 超时的毫秒数。
    • setHost <boolean>: 是否自动添加 Host 请求头。默认为 true
  • callback <Function>
  • 返回: <http.ClientRequest>

发送 HTTP 请求。

如果 url 是一个字符串,则自动使用 url.parse() 解析。 如果 url 是一个 URL, 则自动转换成 options 选项。

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

callback 会作为单次监听器添加到 'response' 事件。

返回的 ClientRequest 是可写流。 如果要通过 POST 请求上传文件,则写入到 ClientRequest

const postData = querystring.stringify({
  'msg': 'Node.js中文网'
});

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

使用 http.request() 必须调用 req.end() 表明请求的结束,即使没有写入数据到请求主体。

如果请求过程中发生错误(DNS 解析错误、TCP 级的错误、或 HTTP 解析错误),则返回的请求对象会触发 'error' 事件。 如果 'error' 事件没有注册监听器,则抛出错误。

以下是需要注意的几个特殊的请求头。

  • 发送 'Connection: keep-alive' 则服务器会保持连接直到下一次请求。

  • 发送 'Content-Length' 会禁用默认的块编码。

  • 发送 'Expect' 会立即发送请求头。通常情况下,当发送 'Expect: 100-continue' 时,需要设置超时时间和 continue 事件的监听器。

  • 发送 Authorization 会代替 auth 计算基本身份验证。

例子,使用 URL 作为 options

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

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

如果请求成功,则依次触发以下事件:

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

    • 多次触发 res'data' 事件(如果响应主体为空,则不会触发 'data' 事件,比如重定向)。
    • res'end' 事件。
  • 'close' 事件。

如果连接出错,则依次触发以下事件:

  • 'socket' 事件。
  • 'error' 事件。
  • 'close' 事件。

如果连接成功之前调用 req.abort(),则依次触发以下事件:

  • 'socket' 事件。
  • (此时调用 req.abort())
  • 'abort' 事件。
  • 'close' 事件。
  • 'error' 事件并带上错误信息 'Error: socket hang up' 和错误码 'ECONNRESET'

如果接收到响应之后调用 req.abort(),则依次触发以下事件:

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

    • 多次触发 res'data' 事件。
  • (此时调用 req.abort())
  • 'abort' 事件。
  • 'close' 事件。

    • res'aborted' 事件。
    • res'end' 事件。
    • res'close' 事件。
  • 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 is preferred over host.
    • family <number> IP address family to use when resolving host and 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 (use one of host:port or socketPath).
    • 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'
  • 'close'
  • 'error' with an error with message 'Error: socket hang up' and code 'ECONNRESET'

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'
  • 'close'

    • 'aborted' on the res object
    • '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.