Node-http模块

1,448 阅读4分钟

学习这个模块,我们尝试在node中使用ts。以下是基本步骤:

1. 创建项目

还是一套熟悉的流程:新建一个空目录,用webstorm打开。

yarn init -y 创建一个package.json,-y 就是默认都选yes。

在目录中新建一个index.ts,要想使用node运行,只需在终端运行命令ts-node-dev index.ts 就会一直自动的重启node程序。

要想在ts文件中引入node模块,是找不到的,因为node是用js写的。所以还需要安装node的声明文件:yarn add --dev @types/node 这句话就会安装所有node的模块,而且是ts类型的声明。安装完后,可以发现在目录中多了个node_modules,依次往下找,就有node下所有的模块:

2. index.ts里使用http模块

已经可以在ts里引入http模块了。

import * as http from 'http';

const server=http.createServer()

server.on('request',(request,response)=>{
    console.log('我被请求了');
    response.end('给你一个响应')
})

server.listen(8888)

用http创建一个server,这就是一个服务器。然后监听这个server的request事件,一旦有人向这个server发请求,就执行我这个回调函数。然后开始监听本机的8888端口。

那怎么向这个server发请求呢?可以使用curl命令:在我们的cmder里,curl http://localhost:8888 ,就是向8888端口发了个请求。

在我们的server里,在开启了node的情况下(ts-node-dev index.ts),终端就对应打印出了'我被请求了'。但是cmder那里一直在等待响应,而我们的server里怎么给响应呢?就是在这个回调里传两个参数:request,response,然后response.end('给你一个响应') 意思就是用响应把这个请求结束掉。然后我们会发现cmder里就会得到这个响应:

3. 深入了解http模块

1. server是什么

我们使用http.createServer() 创建出来的server是什么呢?查询文档可以知道,这个函数返回一个http.Server 实例。也就是说:http.Server是一个类,会创建一个对象我们取名为server

这个server对象上有很多事件和方法,常用的比如request事件,每当有请求时会被触发。所以我们可以用on监听这个request事件。

常用的方法比如listen方法,用于启动这个http服务器。必须调用一次listen方法,这个服务器才启动了。

2. request response 是什么

在监听request事件的回调里,传了两个参数。通过打印request.constructor或者response.constructor 可以知道:

这个request对象属于http.IncomingMessage类,那么同样,这个request上也必然有一些属性和方法:比如

request.httpVersion 表示客户端发送的 HTTP 版本

request.method 返回请求方法,GET POST等

request.url 返回这个请求的路径

request.headers 以键值对的形式返回所有请求头信息

用curl发请求;curl -v http://localhost:8888/xxx -v 可以显示出请求和响应的具体内容;然后在server这边打印出request.headers 结果如下: 是可以对上的。

同理,response对象属于http.ServerResponse类,它可以用哪些属性呢?

response.statusCode 返回状态码,也可以修改

response.end('给你一个响应') 表示响应完成了,必须调用。也可以不传参。

response.write('a') 写响应内容;总之response对象可以控制响应的一切内容。

3. 怎么发POST请求(request的data事件和end事件)

上边用curl直接发的就是GET请求。如果想发POST请求,curl -v -d 'name=anqi' http://localhost:8888/xxx 使用-d 后边接一个数据。这样就是POST请求了。

那我的server怎么获取到用户发的数据呢?也就是怎么获取POST请求的请求体呢?回调里的第一个参数request对象,包含了这个请求的所有信息,这个request对象有data事件:如果监听到用户上传了数据,就会被调用。所以我们可以监听它的data事件,用于获取消息体。

我们知道数据不是一次性发完的,而是分成多个小块,每次发一块。每次发一小块数据,都会触发data事件,所以我们监听data事件,会不断地拿到数据。那怎么知道什么时候数据获取完毕呢?有一个end事件,当没有数据的时候被触发,可以用于把获取到的数据拼接成真正的数据。

const server=http.createServer()
server.on('request',(request: IncomingMessage,response:ServerResponse)=>{
    console.log('我被请求了');
    console.log(request.method)
    let array=[]
    request.on('data',(chunk)=>{
        array.push(chunk)
    })

    request.on('end',()=>{
        console.log('数据已经发送完了');
        const requestBody=Buffer.concat(array).toString() //chunk属于Buffer类
        console.log(requestBody)
        response.end('给你一个响应')
    })
})

server.listen(8888)

这时response.end方法就要放到监听end里了,因为必须把所有数据接收完毕后,才能结束这个响应。