初始化express项目
- npm init 生成package.json
- npm i express -S 安装express
- 新建index.js
const express = require('express'); const app = express(); app.use(function(req,res){ res.end('hello,node!'); }); app.listen(3000); console.log('server running !');
- nodemon index :nodemon上篇已经全局安装了,所以这次可以直接使用了。
- 打开http://localhost:3000/ 又是熟悉的界面
对比与原生node模块,这部分只是调用方法不太一样,接下来看看express对路由对处理方式有啥不一样。
express的路由分发机制
express为开发者提供了一个十分好用的路由分发的机制,我们不用再自己去提取路由,解析路由啥的了。我们只需要这样:
const express = require('express');
const app = express();
app.get('/',function(req,res){
res.end('index');
})
app.use(function(req,res){
res.end('hello node');
})
app.listen(3000);
console.log('server running !');
代码的逻辑是这样的:
假设用户访问了’/’,我就返回 “index”
假设用户访问其他路径,我就返回 “hello node’”
我们的运行结果是这样的
同样的道理我们能给不一样的路径绑定不一样的处理函数,这样可以节省不少重复代码,也可以更好的组织代码结构。
express的内容协商机制
什么是内容协商,就是客户端与服务器在进行数据交换时,会先商量好格式,再进行传输。一般这个格式是由服务器驱动的。举个例子:
app.get('/',function(req,res){
res.end('中文');
})
这里我把回复的字符串返回成中文了,得到的结果是这样的
因为我们没有在服务端指定好编码格式,才是中文出现了乱码,怎么解决这个问题呢,其实我们加一个字母就可以了😂
app.get('/',function(req,res){
res.send('中文');
})
由end 变成send,就可以了 。
send是express为我们封装好的方法,它也会根据返回的数据来匹配一个最合适的编码和数据格式。
res.send(new Buffer('whoop')); // 前端调起一个下载事件
res.send({some:'json'}); // 输出一个json
res.send('<p style="color:red">some html</p>'); // 输出一个带样式的html标签
那我们就直接返回上一篇中用到的index.html试试。
新建index.html 将代码内容复制到文件中,编辑index.js
const express = require('express');
const fs = require('fs');
const app = express();
app.get('/',function(req,res){
res.send(fs.readFileSync(__dirname + '/index.html'));
})
app.use(function(req,res){
res.send('hello node');
})
app.listen(3000);
console.log('server running !');
这里读取文件的方法变了,安装这个代码前端也是会调起一个下载事件的,因为文件读取的时候数据是一个buffer,express会默认这是一个下载资源。所以我们得将buffer转化为文档,这个时候就需要指定一下编码了。
app.get('/',function(req,res){
res.send(fs.readFileSync(__dirname + '/index.html','utf-8'));
})
这样我们的前端界面就传过来了
express的后端逻辑代码
前端界面已经完成,接下来就是后端逻辑代码了,直接复制吗?
直接复制是不行的了,之前原生模块中有一些代码是可以简化了,因为express为我们处理好了。比如路由的解析,请求参数的获取等。
let randomNum = parseInt(Math.random() * 100);
let guessCount = 0;
console.log('randomNum', randomNum);
app.get('/guess', function (req, res) {
const { query } = req; // express已经解析好params并挂到了req上
const guessNumber = Number(query.guessNumber || -1);
if (guessNumber !== -1) {
guessCount++;
if (randomNum === guessNumber) {
res.send(`yes,猜了${guessCount}遍,数字已经重置!`);
randomNum = parseInt(Math.random() * 100);
guessCount = 0;
console.log('randomNum', randomNum);
}
if (randomNum >= guessNumber) {
res.send('too small');
}
if (randomNum <= guessNumber) {
res.send('too big');
}
}
})
如上我们等express版本等猜数字已经完成了。
但是其实express还有一个比较重要的概念:中间件
express的中间件
什么是中间件呢?其实就是将逻辑代码进行细分,然后又串到一起的代码块。它们是由next来进行连接的。
app.get(
'/middleware',
function (req, res, next) {
res.level = 1;
next();
res.send(`第${res.level}层!`)
},
function (req, res) {
res.level = 2;
}
)
上面的代码就定义了一个中间件,假设没有中间件,我们是能在前端得到第一层的,但在这里会是得到:
这里就相当于将第二个function的代码放在第一个function代码的中间执行了,中间件由此得名。
中间件有什么作用呢?可以将代码逻辑分开写,比如请求进来,我先进行一次登录验证,再进行权限验证,最后进行数据查询。那这三部分就可以各是一个中间件了。
总结一下
express对比与原生的node模块还是更加好使用的,提供了很多方便的功能,如路由分发,内容协商,中间件等。但是它还是有问题存在的,所以后面又有了koa。下一篇将使用koa来实现一下。
本篇的源码放在了这里 express版本猜数字,需要的小伙伴可以下载看看。欢迎留言点评,指出不足之处。
另外这个程序其实有bug的,就是不支持多窗口!