使用http模块启动一个服务
使用koa框架实现一个服务器真的很方便。那么如果不使用koa,直接使用node的核心模块,该如何实现一个http服务器呢?node有一个核心模块http,是用来实现http相关功能的。首先让我们回顾下http模块的基本用法吧:
const http = require('http')const httpServer = http.createServer((request, response) => { response.setHeader('Content-Type', 'application/json; charset=utf-8') response.statusCode = 200 response.write(JSON.stringify({code:0, message: 'hello world!'})) response.end()})const port = 3000httpServer.listen(port,'127.0.0.1')console.log('listen on ' + port)
仅仅需要这几行代码,就能实现一个能返回json的服务了。接下来让我们依次解释下代码吧:http.createServer这个方法的功能是生成一个http.server对象。http.server对象是一个EventEmitter,有一个重要的事件就是request,每当服务器收到一个请求后,便会触发request事件。request事件触发后,会给他的回调函数传入两个参数,当前http请求的request对象和response对象。request对象封装了http请求的相关信息。而response则存放了http响应的相关信息,request,response具体内容可查看node官方文档。
第一段代码精简下就是const httpServer = http.createServer(fn),创建了一个http.server对象,赋值(准确说是引用)给httpServer。并为httpServer的request时间传入回调函数。 下面便是httpServer.listen(3000,'127.0.0.1')这句便是让httpServer这个服务监听本地的3000端口。代码运行到这里便初始化完成了。response
当有一个请求过来时,便会触发request事件的回调函数。回调函数第一句是调用了response的setHeader方法,功能是设置响应头,根据http协议,只有响应头的Content-type为 'application/json'时,客户端才会按照json的格式解析响应体。所以我们要想输出一个json,就要先设置好这个响应后。接下来为response的statusCode属性赋值为 200,这个便是http响应码。response.write便是在响应体里写内容,我们写进了一个json字符串。最后调用end方法,结束这个响应。
接下来我们用postman请求一下127.0.0.1:3000/,响应结果如下: 响应体便是我们返回的json。响应头除了我们设置的content-type还增加了三个。通过查询node文档,response对象有个属性sendDate,默认为true,代表若不存在Date响应头,自动为其赋值。其余两个响应头应该也是类似的道理,这里不再赘述。request
这个代码的功能实在是有点太low了,不论什么样的请求都返回同样的响应。一般的服务器都是根据请求来生成响应的。那么我们如何得到请求的数据呢?request事件的回调函数中除了response还有一个request参数呢,这里便能读取url,method等数据。
(request, response) => { let body = ''; request.on('data', (chunk) => { body += chunk.toString(); }) request.on('end', ()=>{ try{ const data = JSON.parse(body) console.log(data) }catch (err){ console.log(err) } }) console.log(request.url) console.log(request.method) console.log(request.headers)
将回调函数改为这段代码,变成读取并在控制台输出请求的url,method,headers和body。url,method,headers都能轻松的读取。http并没有提供方法或属性来直接获取请求体,因此需要自己去写代码解析请求体。由于请求体分为不同的编码格式,压缩格式等,所以解析还是蛮复杂的。上面的代码只能解析json格式的请求体,字符集是‘utf-8’,功能十分有限。
koa脚手架如何使用http模块
我们用koa-generator这个模块来生成一个脚手架。bin里的www便是启动文件,里面的代码主要是:
var app = require('../app');var debug = require('debug')('demo:server');var http = require('http')var port = normalizePort(process.env.PORT || '3000');var server = http.createServer(app.callback());server.listen(port);
可以看出,koa脚手架也是使用了http模块的createServer,listen方法来启动一个服务器的。request事件的回调函数是app.callback(),koa让我们用它提供的方式来构造出这个回调函数。
koa为我们做了什么
我们可以看到通过用node提供的http模块已经能够编写服务器代码了,但要是将所有的业务逻辑都写在那一个回调函数里,代码实在太乱了。所以koa的主要任务就是让我们用他提供的方式去构造出这个回调函数。koa主要为我们做了:
1.封装了ctx 2.中间件 3.解析请求体(koa-bodyparser) 4.解析路由(koa-router) 接下来我们来一一去看koa是如何实现的这些功能。