每天学点node系列-http

任何可以使用JavaScript来编写的应用,最终会由JavaScript编写。--Atwood's Law

http模块概览

http模块主要用于创建http server服务,并且

  • 支持更多特性
  • 不缓冲请求和响应
  • 能够流式传输数据

借助http模块,可以几行代码就搞定一个超迷你的web server:

var http=require("http")
http.createServer(function(req, res){
    res.writeHead(200,{
        "content-type":"text/plain"
    })
    res.write("hello nodejs")
    res.end()
}).listen(3000)

http服务器

像上面一样使用的createServer方法返回了一个http.Server对象,这其实是一个创建http服务的捷径,如果我们用以下代码来实现的话,也将一样可行

var http = require("http")
var server = new http.Server()
server.on("request", function(req, res){
        res.writeHead(200, {
        "content-type":"text/plain"
    })
    res.write("hello nodejs")
    res.end()
})
server.listen(3000)

以上代码是通过直接创建一个http.Server对象,然后为其添加request事件监听,其实也就说createServer方法其实本质上也是为http.Server对象添加了一个request事件监听。

http.Server的事件

http.Server继承自 net.Server,http.Server提供的事件如下:

  • request:当客户端请求到来时,该事件被触发,提供两个参数req和res,表示请求和响应信息,是最常用的事件
  • connection:当TCP连接建立时,该事件被触发,提供一个参数socket,是net.Socket的实例
  • close:当服务器关闭时,触发事件(注意不是在用户断开连接时)

正如上面我们所看到的request事件是最常用的,而参数req和res分别是http.IncomingMessage和http.ServerResponse的实例,那么我们来看看这两个类

http.IncomingMessage

**在server端:获取请求发送方的信息,比如请求方法、路径、传递的数据等。 **
在client端:获取 server 端发送过来的信息,比如请求方法、路径、传递的数据等。

http.IncomingMessage实例 有三个属性需要注意:method、statusCode、statusMessage。

  • method:只在 server 端的实例有(也就是 serverReq.method)
  • statusCode/statusMessage:只在 client 端 的实例有(也就是 clientRes.method)

并且其提供了3个事件,如下

  • data:当请求体数据到来时,该事件被触发,该事件提供一个参数chunk,表示接受的数据,如果该事件没有被监听,则请求体会被抛弃,该事件可能会被调用多次(这与nodejs是异步的有关系)
  • end:当请求体数据传输完毕时,该事件会被触发,此后不会再有数据
  • close:用户当前请求结束时,该事件被触发,不同于end,如果用户强制终止了传输,也是用close

http.ServerResponse

http.ServerResponse 的作用很明确,服务端通过http.ServerResponse 实例,来个请求方发送数据。包括发送响应表头,发送响应主体等。它决定了用户最终看到的内容,一般也由http.Server的request事件发送,并作为第二个参数传递,它有三个重要的成员函数,用于返回响应头、响应内容以及结束请求

  • res.writeHead(statusCode,[heasers]):向请求的客户端发送响应头,该函数在一个请求中最多调用一次,如果不调用,则会自动生成一个响应头
  • res.write(data,[encoding]):想请求的客户端发送相应内容,data是一个buffer或者字符串,如果data是字符串,则需要制定编码方式,默认为utf-8,在res.end调用之前可以多次调用
  • res.end([data],[encoding]):结束响应,告知客户端所有发送已经结束,当所有要返回的内容发送完毕时,该函数必需被调用一次,两个可选参数与res.write()相同。如果不调用这个函数,客户端将用于处于等待状态。

http客户端

http模块提供了两个函数http.request和http.get,功能是作为客户端向http服务器发起请求。

var http = require('http')

// http server
var server = http.createServer(function(req, res){
    var url = req.url
    res.end( '您访问的地址是:' + url )
})

server.listen(3000)

// http client
var client = http.get('http://127.0.0.1:3000', function(res){
    res.setEncoding("utf-8")
    res.on("data",function(chunk){
        console.log(chunk.toString()) 
    })
    console.log(res.statusCode);
})

client.on("error",function(err){ 
    console.log(err.message)
})
client.end()

http.ClientRequest

此对象由 http.request() 内部创建并返回。 它表示正在进行的请求,且其请求头已进入队列。 请求头仍然可以使用 setHeader(name, value)getHeader(name)removeHeader(name) 改变。 实际的请求头将与第一个数据块一起发送,或者当调用 request.end() 时发送。
要获得响应,则为请求对象添加 'response' 事件监听器。 当接收到响应头时,将、则会从请求对象触发 'response' 事件。 'response' 事件执行时有一个参数,该参数是 http.IncomingMessage 的实例。

'response' 事件期间,可以添加监听器到响应对象,比如监听 'data' 事件。

如果没有添加 'response' 事件处理函数,则响应将被完全丢弃。 如果添加了 'response' 事件处理函数,则必须消费完响应对象中的数据,每当有 'readable' 事件时调用 response.read()、或添加 'data' 事件处理函数、或通过调用 .resume() 方法。 在消费完数据之前,不会触发 'end' 事件。 此外,在读取数据之前,它将占用内存,最终可能导致进程内存不足的错误。

Node.js 不检查 Content-Length 和已传输的主体的长度是否相等。

请求继承自流,且额外实现以下内容:

  • 'abort': 当请求被客户端中止时触发。 此事件仅在第一次调用 abort() 时触发。
  • 'timeout':当底层套接字因不活动而超时时触发。 这只会通知套接字已空闲。 必须手动中止请求。
  • ...
posted @ 2019-07-08 21:13  一半水一半冰  阅读(400)  评论(2编辑  收藏  举报
Fork me on GitHub