Node.js的高效I/O处理,使其不仅适合做为服务器提供HTTP服务,也可以做为HTTP客户端访问和使用HTTP服务。在HTTP服务中,有两个重要的概念:URL和方法。使用最多的是用于请求内容的GET方法,除GET方法外还有其它方法,如:POST、PUT、DELETE、HEAD,使用不同的方法访问服务器可以得到不同的响应结果。
1. 创建HTTP客户端
http
模块提供了两个创建HTTP客户端的方法http.request
和http.get
,以向HTTP服务器发起请求。http.get
是http.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.ClientRequest
由http.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.Agent
HTTP代理对象
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代理中,这个名称包含CA
,cert
,ciphers
,和其他HTTPS/TLS特殊选项来决定一个套接字是否可以再生。
3.3 http.Agent
对象中属性
agent.maxSockets
默认值为 Infinity。决定了每台主机上的 agent 可以拥有的并发 socket 的打开数,主机可以是 host:port
或 host:port:localAddress
。
agent.maxFreeSockets
默认设置为256。对于支持HTTP KeepAlive的Agent,这个属性设置了在空闲状态下仍然打开的套接字数量的最大值。
agent.sockets
一个保存当前被代理使用的套接字的数组对象。 请不要修改。
agent.freeSockets
一个当使用HTTP KeepAlive时保存当前等待用于代理的数组对象。 请不要修改。
agent.requests
一个保存还没有指定套接字的请求队列对象。 请不要修改。