路由
接触到一个新的框架时,首先要了解的就是路由,路由是指应用程序的端点 (URI) 如何响应客户端请求,简单来讲就是定义通过什么路径来访问各个服务,每个路由可以有一个或多个处理函数,当路由匹配时执行。
再写路由使用之前 先来分析一下 项目的入口文件
入口文件 app.js 分析
app.js文件 相当于项目启动的入口文件,里面会有一些项目公共方法和服务器配置等,具体分析如下
引入 createError(http 错误处理模块)、express(express主包)、 path(文件与目录路径处理模块)、 cookieParser(cookiee处理模块) 、logger(日志模块)这几个主包和引入路由文件和创建express应用
代码语言:javascript复制var createError = require('http-errors');
var express = require('express');
var path = require('path'); //
var cookieParser = require('cookie-parser');
var logger = require('morgan');
var indexRouter = require('./routes/index'); // 引入路由目录rotes中的index
var usersRouter = require('./routes/users'); // 引入路由目录rotes中的users
var app = express();
代码语言:javascript复制// view engine setup
app.set('views', path.join(__dirname, 'views')); // 定义页面目录
app.set('view engine', 'jade'); // 页面模板引擎
app.use(logger('dev')); // 日志打印级别
app.use(express.json()); // JSON格式处理数据
使用 urlencoded处理数据 有效负载解析传入请求, 是express 基于body-parser 的 内置中间件
此选项允许在使用querystring库 (when false) 或qs库 (值为 true时)解析 URL 编码数据之间进行选择。
“扩展”语法允许将丰富的对象和数组编码为 URL 编码格式,从而实现类似 JSON 的 URL 编码体验
有关更多信息,请参阅 qs 库。
代码语言:javascript复制app.use(express.urlencoded({ extended: false }));
app.use(cookieParser()); // 使用cookie 处理对象
app.use(express.static(path.join(__dirname, 'public'))); // 静态资源目录
app.use('/', indexRouter); // 指向 index.js路由
app.use('/users', usersRouter); // 指向 user.js 路由
// 404错误处理
app.use(function(req, res, next) {
next(createError(404));
});
// error handler 其他错误处理
app.use(function(err, req, res, next) {
// 设置 locals 只在 开发坏境生效
res.locals.message = err.message;
res.locals.error = req.app.get('env') === 'development' ? err : {};
// 返回错误http 状态吗
res.status(err.status || 500);
// 渲染错误页面
res.render('error');
});
module.exports = app;
请求方式
get请求路由
get请求最为简单,看一下routers目录下的index.js 文件,修改掉 title的值 然后重新运行npm run start,用浏览器 打开http://localhost:3000 查看项目 可以看到之前的Express 换成了 Hello Word!
代码语言:javascript复制var express = require('express');
var router = express.Router();
/* 首页路由. */
router.get('/', function(req, res, next) {
// render的第一个参数 index是指views下的 index.jade 模板
// 第二个参数 是指传入到模板的参数对象,可以将次数据渲染到页面上
res.render('index', { title: 'Hello Word!' });
});
module.exports = router;
其他请求方式路由
另外的几个请求方式 就是 POST PUT DELETE 也很简单,直接使用方式如下
POST 请求方式
代码语言:javascript复制router.post('/iwhao', function(req, res, next) {
res.render('index', { title: 'Hello Word!' });
});
PUT 请求方式
代码语言:javascript复制router.put('/iwhao', function(req, res, next) {
res.render('index', { title: 'Hello Word!' });
});
DELETE 请求方式
代码语言:javascript复制router.delete('/iwhao', function(req, res, next) {
res.render('index', { title: 'Hello Word!' });
});
自定义路由
分析过上文首页路由,可以尝试自定义一个新的路由 例如
代码语言:javascript复制router.get('/wh', function(req, res, next) {
// render的第一个参数 index是指views下的 index.jade 模板
// 第二个参数 是指传入到模板的参数对象,可以将次数据渲染到页面上
res.render('index', { title: 'Hello Word!' });
});
重新运行 npm run start 后访问 http://localhost:3000/wh 效果和上方一样,说明应生效了,
但每次 修改后都需要 运行命令 是不是 感觉 很不方便,开发效率也很低下,下面介绍 一个热更新工具 nodememon
nodememon
安装
代码语言:javascript复制npm install nodemon
安装完 在项目根目录中 package.json 文件中将其中 的 scripts修改 成一下代码
代码语言:javascript复制"scripts": {
"start": "nodemeon ./bin/www"
}
然后再执行 npm start 命令启动项目,这样在路由文件被修改后,会自动重启项目,刷新浏览器直接更新
路由匹配规则
上文中的路由匹配都是完整匹配,/wh 浏览器输入 /wh 才能匹配到,除了完整匹配,还支持模糊匹配
//能够匹配 /iwhatop、/iwhatop
代码语言:javascript复制router.get('/iwhao?top', function(req, res, next) {
res.render('index', { title: 'Hello Word' });
});
能够匹配 /iwhaootop、/iwhaoooootop.top
代码语言:javascript复制router.get('/iwhao top', function(req, res, next) {
res.render('index', { title: 'Hello Word' });
});
能够匹配 /iwhaotop 、 /itop
代码语言:javascript复制router.get('/i(whao)?top', function(req, res, next) {
res.render('index', { title: 'Hello Word' });
});
能够匹配 /iwhaotop 、/iwhao.top 、 /iwhao-top
代码语言:javascript复制router.get('/iwhao*top', function(req, res, next) {
res.render('index', { title: 'Hello Word' });
});
能够匹配 /iwhaotop 、/iwhao.top 、 /iwhao-top
代码语言:javascript复制router.get('/iwhao*top', function(req, res, next) {
res.render('index', { title: 'Hello Word' });
});
同时还支持正则表达式
代码语言:javascript复制// 能够匹配到路径中包含 iwhao 字段的任何内容 /iwhaotop 、/iwhao.top 、 /iwhao-top
router.get(/iwhao/, function(req, res, next) {
res.render('index', { title: 'Hello Word' });
});
中间件
在实际项目中,有时候需要公通方法来拦截请求,比如访问一些比较私密的信息(如用户个人信息等)之前,需要做一些身份验证
如果只有一两个接口需要验证,那就在需要的接口里单独处理就可以了,但是如果很多都需要,就不可能每个接口都单独处理一遍,这是就应该把公共的处理代码 提出来公用。
express 就提供一个很好的工具 ,叫中间件,简单来说 中间件就是一些处理方法的合集,使用起来很简单,一个关键点就是 就是上文路由方法中的 next,下面是 简单模拟例子
代码语言:javascript复制router.get('/zjj/:status', function(req, res, next) {
console.log(req.params.status);
// 这里是中间件要处理的逻辑代码 start
console.log('我是中间件')
if(req.params && req.params.status === 'yes') {
res.send('通过');
}
// 这里是中间件要处理的逻辑代码 end
next() // 继续下一步,执行下一个中间件
},function(req, res, next){
res.send('拒绝');
});
然后浏览器访问
http://localhost:3000/zjj/yes 页面打印的是通过
http://localhost:3000/zjj/no 页面打印的是拒绝
上述代码中router.get的第二个参数是个方法,而这个路由的处理方法就是express 中的中间件
***
具体参数说明
参数 | 描述 |
---|---|
req | 请求数据对象 Request |
res | 返回数据对象 Response |
next | 执行下一步函数 |
start 和 end中间 的处理 我这里是只是简单模拟一下,真正项目中肯定是单独抽出模块,引入来具体鉴定权限
***