详解Node.js的http模块之HTTP客户端介绍

 2015年08月30日    1723     声明


Node.js的高效I/O处理,使其不仅适合做为服务器提供HTTP服务,也可以做为HTTP客户端访问和使用HTTP服务。在HTTP服务中,有两个重要的概念:URL和方法。使用最多的是用于请求内容的GET方法,除GET方法外还有其它方法,如:POST、PUT、DELETE、HEAD,使用不同的方法访问服务器可以得到不同的响应结果。

  1. 创建HTTP客户端
  2. 类:http.ClientRequest客户端请求对象
  3. 类:http.AgentHTTP代理对象


1. 创建HTTP客户端

http模块提供了两个创建HTTP客户端的方法http.requesthttp.get,以向HTTP服务器发起请求。http.gethttp.request快捷方法,该方法仅支持GET方式的请求。

1.1 使用http.request(options, callback)创建HTTP请求

http.request()方法会返回一个http.ClientRequest类的实例。ClientRequest实例是一个可写流对象,与服务器的数据传输就是基于此对象,如:需要用POST请求上传一个文件的话,就是将其写入到ClientRequest对象。

options可以是一个对象或一个字符串。如果options是一个字符串, 它将自动使用url.parse()解析。如果是一个对象,可能包含以下值:

  • host:请求的服务器域名或 IP 地址。默认:'localhost'
  • hostname:用于支持 url.parse()hostname优于host
  • port:远程服务器端口。 默认: 80.
  • localAddress:用于绑定网络连接的本地接口
  • socketPath:Unix域socket(使用host:port或socketPath)
  • method:HTTP请求方法。默认:'GET'
  • path:请求路径。默认:'/'。如果有查询字符串(查询参数),则需要包含。例如'/index.html?page=12'。请求路径包含非法字符时抛出异常。目前,只有空格不支持,以后可能改变。
  • headers:包含请求头的对象
  • auth:用于计算认证头的基本认证,即 user:password
  • agent:控制Agent的行为。当使用了一个Agent的时候,请求将默认为Connection: keep-alive。可能的值为:
    • undefined (default):在这个主机和端口上使用 global Agent
    • Agent object:在Agent中显式使用 passed
    • false:选择性停用连接池,默认请求为:Connection: close
  • keepAlive:{Boolean} 用于保持资源池周围的socket,未来可能会用于其它请求。默认值为false
  • keepAliveMsecs:{Integer} 使用HTTP KeepAlive的时候,通过正在保持活动的sockets发送TCP KeepAlive包的频繁程度。默认值为1000。仅当keepAlive为true时才可用。


1.2 http.get(options, callback)创建HTTP GET请求

http.get()方法是一个快捷方法,在HTTP请求中,使用最多的是没有报文体的 GET 请求,所以Node提供了这个简便的方法。和 http.request()不同点在于,这个方法会自动设置HTTP请求方式为GET,并自动调用req.end()方法。


2. 类:http.ClientRequest客户端请求对象

http.ClientRequesthttp.request()http.get()创建返回。它表示着一个 正在处理的HTTP请求,其头部已经进入请求队列,但仍然可以通过setHeader(name, value), getHeader(name),removeHeader(name)等API修改头部。实际的头部会随着第一个数据块发送,或在连接关闭时发送。

通过http.request()方法的callback参数或'response'事件监听器,可以获得服务端响应对象,方对象是一个http.IncomingMessage实例。

'response'事件期间,可以为响应对象添加监听器,尤其是监听'data'事件,即可获取服务端响应数据。如果没有添加'response'处理函数,响应将被完全忽略。然而,如果你添加了一个'response'事件处理函数,那么你 必须消费掉响应对象的数据,如:在'readable'事件时调用response.read(),可以添加一个'data'处理函数,也可以调用.resume()方法暂停响应流。数据被消费掉后,'end'事件被触发。如果数据未被读取,它将会消耗内存,最终产生'process out of memory'错误。

http.ClientRequest是一个Writable Stream,同时还是一个EventEmitter


2.1 http.ClientRequest中的事件

事件:'response',监听函数function (response) { }

当接收到请求的响应时触发,该事件只被触发一次。response参数是http.IncomingMessage的一个实例。

事件:'socket',监听函数function (socket) { }

Socket 附加到这个请求的时候触发。

事件:'connect',监听函数function (response, socket, head) { }

每次服务器使用 CONNECT 方法响应一个请求时触发。如果该事件未被监听,接收 CONNECT 方法的客户端将关闭它们的连接。

事件:'upgrade',监听函数function (response, socket, head) { }

每次服务器返回upgrade响应时触发。如果该事件未被监听,客户端收到upgrade后将关闭连接。

事件:'continue',监听函数function () { }

当服务器发送100 Continue响应时触发,通常是因为请求包含Expect: 100-continue。该指令表示客户端应发送请求体。


2.2 http.ClientRequest中的方法

request.flushHeaders()

刷新请求的头

request.write(chunk, [encoding])

发送一块请求体。通过多次调用这个函数,用户可以流式地发送请求体至服务器。在这种情况下,创建请求时建议使用['Transfer-Encoding', 'chunked']头。

参数:chunk 必须是Buffer或字符串。encoding参数是可选的, 只能在 chunk 是 string 类型的时候才能设置,默认是 'utf8'

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

结束发送请求。如果请求体中还有未发送数据,该函数将会把它们flush到流中。如果该请求是分块的,该方法将会发送终结符0\r\n\r\n

如果指定了data,那么相当于 先调用request.write(data, encoding)方法,再调用request.end()方法。

request.abort()

终止一个请求。

request.setTimeout(timeout, [callback])

一旦一个套接字被分配给该请求并且完成连接,socket.setTimeout()将会被调用。

request.setNoDelay([noDelay])

一旦一个套接字被分配给该请求并且完成连接,socket.setNoDelay()将会被调用。

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

一旦一个套接字被分配到这个请求,而且成功连接,那么socket.setKeepAlive()就会被调用。


3. 类:http.AgentHTTP代理对象

http.Agent是会把套接字做成资源池。当HTTP客户端请求需要自定义一些自定义的代理参数(如:主机的套接字并发数、套接字发送TCP KeepAlive包的频率等),可以设置此对象。该对象由构选函数new Agent([options])创建返回。

3.1 new Agent([options])创建Agent对象

http.request默认使用http.globalAgent,如果要修改默认值就需要创建一个Agent对象。

options是一个包含以下值的对象:

  • keepAlive:{Boolean} 保持在资源池周围的Socket套接字,可被其它请求使用。默认值为 false
  • keepAliveMsecs:{Integer} 使用HTTP KeepAlive的时候,通过正在保持活动的sockets发送TCP KeepAlive包的频繁程度。默认值为1000,仅当 keepAlive 为 true 时才可用。
  • maxSockets:{Number} 每台主机允许的socket的最大值。默认值为Infinity。
  • maxFreeSockets:{Number} 在空闲状态下,还依然开启的 socket 的最大值。仅当keepAlive


3.2 http.Agent对象中方法

agent.destroy()

销毁被此agent占用的任何套接字

agent.getName(options)

获取一组请求选项的唯一名,来确定某个连接是否可重用。在http代理中,它将返回host:port:localAddress。在https代理中,这个名称包含CAcertciphers,和其他HTTPS/TLS特殊选项来决定一个套接字是否可以再生。


3.3 http.Agent对象中属性

agent.maxSockets

默认值为 Infinity。决定了每台主机上的 agent 可以拥有的并发 socket 的打开数,主机可以是 host:porthost:port:localAddress

agent.maxFreeSockets

默认设置为256。对于支持HTTP KeepAlive的Agent,这个属性设置了在空闲状态下仍然打开的套接字数量的最大值。

agent.sockets

一个保存当前被代理使用的套接字的数组对象。 请不要修改。

agent.freeSockets

一个当使用HTTP KeepAlive时保存当前等待用于代理的数组对象。 请不要修改。

agent.requests

一个保存还没有指定套接字的请求队列对象。 请不要修改。