http.ClientRequest 类小结(端午已过,继续学习)

1,204 阅读4分钟

之前我们学到过,关于http.Agent。其得作用就是为了给ClientRequest使用的。

http模块提供了两个函数http.request()和http.get(),帮助程序向服务器端发送请求。

前面 提到get其实就是request的简易版本,故这就不在深入讨论get的相关知识,把重点放在request上。

我们可以通过http.request ()方法创建一个发送请求的http.ClientRequest类实例并return出来。

请求创建后,并不会立即发送请求,我们还可以继续访问请求头:setHeader(name, value)、getHeader(name) 和 removeHeader(name) API 进行修改。实际的请求头会与第一个数据块一起发送或当调用 request.end()<真正发送请求的api> 时发送。

let request = http.request(
  {
    protocol: 'http:',     // 请求的协议
    host: 'ranhao.com',   // 请求的host
    port: 8080,              // 端口
    method: 'GET',         // GET请求
    timeout: 1000,         // 超时时间
    path: '/'              // 请求路径
  },
  res => {  // 连接成功,回调函数触发
    // res => http.IncomingMessage实例,是一个可读流
    res.on('data', data => {
      console.log(data.toString('utf8')); // 打印返回的数据。
    });
  }
);

request.setHeader('Cache-Control', 'max-age=0');
request.getHeader('Cache-Control');
request.end(); // 此时才发送请求

http.ClientRequest类继承了EventEmitter,它设置了如下的触发器。(客户端代表我们的node)

我们可以谁知一些监听器来获取有用的消息

  • abort

当请求已被客户端终止时触发。 该事件仅在首次调用 abort() 时触发。

  • connect

每当服务器响应 CONNECT 请求时触发。如果该事件未被监听,则接收到 CONNECT 方法的客户端会关闭连接。

  • information

服务器发送 1xx 中间响应(不包括 101 Upgrade)时触发。

你设置的监听器将会接收一个对象,该对象包含 HTTP 版本,状态码,状态消息,键值对请求头对象、以及具有原始请求头名称和值的数组。

const http = require('http');

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

// 发出请求。
const req = http.request(options);
req.end();

req.on('information', (info) => {
  console.log(`获得主响应之前的信息: ${info.statusCode}`);
});

具体信息自行移步官网,本教程不罗列字典信息。

  • response

当收到此请求的响应时触发。 接受的参数为 <http.IncomingMessage>实例,为可读流。

该事件只触发一次。如果没有添加 'response' 监听器,则响应会被整个丢弃。

如果你添加了 'response' 监听器,则必须消耗完响应对象的数据,

可通过调用 response.read()、或添加一个 'data' 事件处理函数、或调用 .resume() 方法。

数据被消耗完时会触发 'end' 事件。

在数据被读取完之前会消耗内存,可能会造成 'process out of memory' 错误。

  • socket

暂不解释,移步net模块教程。当 socket 被分配到请求后触发。

  • timeout

当底层套接字因不活动而超时时触发。 这只会通知套接字已空闲。 必须手动中止请求。

  • upgrade

每次服务器响应升级请求时发出。 如果未监听此事件且响应状态码为 101 Switching Protocols,则接收升级响应头的客户端将关闭其连接。

一些触发器了解了过后,我们可以再了解一些实例的方法api,他可以使我们更加方便地对客户端请求实例做一些基础地操作,而不用老是去监听这监听那,触发来触发去的。使用这些方法的依然是http.request()方法创建一个发送请求的http.ClientRequest类实例并return出来的那位仁兄。

写太多api没有意义,等于写字典,字典官网罗列的很好,我这就打算加上一些重点的api。

  • request.aborted

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

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

    完成发送请求。 如果部分请求主体还未发送,则将它们刷新到流中。 如果请求被分块,则发送终止符 '0\r\n\r\n'。

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

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

  • request.destroy

    取消请求,触发close监听器。

  • getHeader setHeader removeHeader

    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''text/html'。
    const contentLength = request.getHeader('Content-Length');
    // 'contentLength' 的类型为数值。
    const cookie = request.getHeader('Cookie');
    // 'cookie' 的类型为字符串数组。
    ```s
    
  • maxHeadersCount

    限制最大响应头数。 如果设置为 0,则不会应用任何限制。默认2000

  • write

发送请求主体的一个数据块。

通过多次调用该方法,一个请求主体可被合成发送到一个服务器,在这种情况下,当创建请求时,建议使用 ['Transfer-Encoding', 'chunked'] 请求头