学习使用ExpressJS 4.0中的新Router的用法


Posted in Javascript onNovember 06, 2018

概述

ExpressJS 4.0中提出了新的路由Router。Router好比是一个“迷你版”的express应用,它没有引入views或者settings,但是提供了路由应有的API,.use,.get,.param和route。

示例应用

让我们创建一个express应用,仅仅有少量routes和功能:

  • 基础路由:Home,About
  • 一个把request请求打印到console的路由中间件
  • 一个带参数的路由
  • 一个校验特殊参数的路由中间件
  • 一个用于登录的路由,响应对与路径/login的GET和POST请求
  • 校验功能:校验传递给某一个路由的参数

应用文件架构

我们只需要两个文件:

- package.json // 构建node应用所需要的插件
- server.js   // 构建示例应用的启动文件

我们会把路由代码写如server.js文件。将来为了让示例应用模块化,我们会把这些路由代码分别写入不同的文件,甚至可以为网站的不同组成部分单独定义不同的路由文件。

创建Node应用

创建node应用,我们需要编写package.json文件去定义node应用依赖的插件。

{
  "name": "express-router-experiments",
  "main": "server.js",
  "dependencies": {
    "express": "~4.0.0"
  }
}

下面继续安装依赖:

$ npm install

现在我们安装了Express,让我们继续编写server.js去处理路由。

创建server

我们在package.json中指定了main属性值为server.js,因此Express会使用server.js作为应用的入口文件。

// server.js

// 基础设置
// ==============================================

var express = require('express');
var app   = express();
var port  =  process.env.PORT || 8080;

// 路由
// ==============================================

// 示例路由
app.get('/sample', function(req, res) {
  res.send('this is a sample!'); 
});

// 我们会在这里编写自己的路由

// 启动server
// ==============================================
app.listen(port);
console.log('Magic happens on port ' + port);

现在我们可以使用命令node server.js启动server。我们使用app.get创建了一个Express 3时代的路由,如果此时打开浏览器访问http://localhost:8080/sample,我们就能看到这样下面的文字:this is a sample!。

基本用法 express.Router()

下面我们一起编写Node应用前端路由的例子,包括Home页面和About页面。

// server.js

...

// 获取router实例
var router = express.Router();

// home页面路由(http://localhost:8080)
router.get('/', function(req, res) {
  res.send('im the home page!'); 
});

// about页面路由(http://localhost:8080/about)
router.get('/about', function(req, res) {
  res.send('im the about page!'); 
});

// 把定义好的路由集成到Node应用中
app.use('/', router);

...

我们前面的代码使用express.Router()生成一个路由实例,并定义路由规则,最后把这个路由实例集成到应用中。现在我们可以通过http://localhost:8080访问Home页面,通过http://localhost:8080/about访问about页面。

请注意:我们可以改变前面定义的路由中默认的根路径('/')。如果我们把app.use('/', router)改为app.use('/app', router),那么home页面的访问地址变为http://localhost:8080/app,about页面的访问地址变为http://localhost:8080/app/about。

这是一个非常有用的功能,我们可以利用它创建多个路由实例express.Router()并把这些实例都集成到Node应用中。例如,可以在Node应用中针对不同功能需求创建不同的路由:一个基础路由,一个用于权限校验的路由和其他API路由。如此一来,Node应用变得更加模块化更容易扩展。

创建路由中间件Router.use()

路由中间件实际是一种允许一个request请求被处理之前进行某些操作的机制。例如,在把一个request请求的响应数据返回给用户之前,我们可以检查用户是否有权限,可以记录日志等等。
下面我们实现一个打印日志的中间件,每次有一个request请求,我们就在console打印一条信息。

// server.js

...

// 获取router实例
var router = express.Router();

// 路由中间件:每当有一个request请求都会执行
router.use(function(req, res, next) {

  // 打印request的method和url
  console.log(req.method, req.url);

  // 继续处理request请求,寻找匹配的路由
  next(); 
});

// home页面路由 (http://localhost:8080)
router.get('/', function(req, res) {
  res.send('im the home page!'); 
});

// about页面路由 (http://localhost:8080/about)
router.get('/about', function(req, res) {
  res.send('im the about page!'); 
});

// 把定义好的路由集成到Node应用中
app.use('/app', router);

...

我们用router.use()用来定义了路由中间件,并且把它应用到所有访问我们Node应用的请求上。打开浏览器访问http://localhost:8080/app,我们可以看到console打印的信息:im the home page!。

在代码中,中间件和路由的位置顺序非常重要。一个request请求到来时,它们会按照代码中的先后顺序依次执行。这就意味着如果你把中间件写在某一个路由的后面,路由会拦截这个request请求并完成响应,中间件则永远不会被执行。

带参数的路由 /hello/:name

我们想要在URL中传递一个人的名字name,让NODE应用输出 Hello name! 这里可以使用带参数的路由。

// server.js
...
// 获取router实例
var router = express.Router();
...

// 带参数的路由 (http://localhost:8080/hello/:name)
router.get('/hello/:name', function(req, res) {
  res.send('hello ' + req.params.name + '!');
});

// 把定义好的路由集成到Node应用中
app.use('/', router);
...

现在我们访问http://localhost:8080/hello/holly就可以看到浏览器页面展示的信息:

Hello holly!

创建参数中间件

如果想要校验上面传入URL的人的名字,确保名字是符合规范的,我们需要在路由中间件中去校验URL中的参数name。它有个特殊的名字,参数中间件。我们可以使用express.param()去创建它。

// server.js
...

// 获取router实例
var router = express.Router();

...

// 参数中间件 校验name参数
router.param('name', function(req, res, next, name) {
  // 在这里进行校验操作
  console.log('doing name validations on ' + name);

  // 校验通过我们把校验后的名字赋值给req对象
  req.name = name;
  // 继续处理request请求,寻找匹配的路由
  next(); 
});

// 带参数的路由 (http://localhost:8080/hello/:name)
router.get('/hello/:name', function(req, res) {
  res.send('hello ' + req.name + '!');
});

// 把定义好的路由集成到Node应用中
app.use('/', router);

现在当我们访问到/hello/:name路由,我们编写的参数中间件就会介入并做相应的校验处理。校验通过我们把校验后的名字赋值给req对象,并在相应的.get路由中使用req.name获取校验后的名字。打开浏览器,访问http://localhost:8080/hello/sally,我们可以看到浏览器展示的信息:

Hello sally!

console控制台打印出:

doing name validations on sally

如果你使用RESTful API,你甚至可以校验token是否有效,来判断用户是否有权限访问。

链式路由

我们也可以直接在app对象上创建路由。利用app.route()可以针对一个路由定义多个路由处理函数。例如,对/login路由发起get请求,展示登录界面,同时也可以对/login路由发起post请求,提交登录表单信息。我们就可以使用app.route来创建这个/login路由。

// ROUTES
// ==============================================

app.route('/login')

  // 展示登录界面 (GET http://localhost:8080/login)
  .get(function(req, res) {
    res.send('this is the login form');
  })

  // 提交登录表单 (POST http://localhost:8080/login)
  .post(function(req, res) {
    console.log('processing');
    res.send('processing the login form!');
  });

...

总结

使用Express 4.0中的路由,我们可以更灵活的定义路由:

  • 多次使用express.Router()定义一组路由
  • 使用express.Router()划分模块,并用app.use()把他们整合起来
  • 使用路由中间件对request请求进行预处理
  • 使用参数中间.param()件对URL中参数进行校验
  • 使用app.route()创建链式路由

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
ExtJS4 Grid改变单元格背景颜色及Column render学习
Feb 06 Javascript
js重写alert控件(适合学习js的新手朋友)
Aug 24 Javascript
js实现可兼容IE、FF、Chrome、Opera及Safari的音乐播放器
Feb 11 Javascript
JavaScript使用pop方法移除数组最后一个元素用法实例
Apr 06 Javascript
DOM操作和jQuery实现选项移动操作的简单实例
Jun 07 Javascript
浅析ES6的八进制与二进制整数字面量
Aug 30 Javascript
基于jQuery实现咖啡订单管理简单应用
Feb 10 Javascript
微信小程序实现顶部普通选项卡效果(非swiper)
Jun 19 Javascript
ReactNative之FlatList的具体使用方法
Nov 29 Javascript
Vue隐藏显示、只读实例代码
Jul 18 Javascript
vue获取data数据改变前后的值方法
Nov 07 Javascript
JS出现404错误原理及解决方案
Jul 01 Javascript
vue项目上传Github预览的实现示例
Nov 06 #Javascript
React Component存在的几种形式详解
Nov 06 #Javascript
支付宝小程序tabbar底部导航
Nov 06 #Javascript
利用JavaScript缓存远程窃取Wi-Fi密码的思路详解
Nov 05 #Javascript
利用hasOwnProperty给数组去重的面试题分享
Nov 05 #Javascript
微信小程序实现底部导航
Nov 05 #Javascript
对 Vue-Router 进行单元测试的方法
Nov 05 #Javascript
You might like
骨王战斗力在公会成员中排不进前五,却当选了会长,原因竟是这样
2020/03/02 日漫
Ajax PHP简单入门教程代码
2008/04/25 PHP
smarty模板引擎中内建函数if、elseif和else的使用方法
2015/01/22 PHP
PHP实现多维数组转字符串和多维数组转一维数组的方法
2015/08/08 PHP
php实现网站留言板功能
2015/11/04 PHP
IE与Firefox下javascript getyear年份的兼容性写法
2007/12/20 Javascript
js 获取Listbox选择的值的代码
2010/04/15 Javascript
js中页面的重新加载(当前页面/上级页面)及frame或iframe元素引用介绍
2013/01/24 Javascript
封装属于自己的JS组件
2016/01/27 Javascript
js动态获取子复选项并设计全选及提交的实现方法
2016/06/24 Javascript
JS实现六位字符密码输入器功能
2016/08/19 Javascript
JS中用try catch对代码运行的性能影响分析
2016/12/26 Javascript
nodejs入门教程五:连接数据库的方法分析
2017/04/24 NodeJs
Angular 项目实现国际化的方法
2018/01/08 Javascript
JS实现HTML页面中动态显示当前时间完整示例
2018/07/30 Javascript
js canvas实现红包照片效果
2018/08/21 Javascript
浅谈vuex actions和mutation的异曲同工
2018/12/13 Javascript
vue中$nextTick的用法讲解
2019/01/17 Javascript
详解webpack引用jquery(第三方模块)的三种办法
2019/08/21 jQuery
vue中echarts引入中国地图的案例
2020/07/28 Javascript
js+canvas实现画板功能
2020/09/13 Javascript
[01:45]2014DOTA2 TI预选赛预选赛 战前探营!
2014/05/21 DOTA
Python正则表达式完全指南
2017/05/25 Python
python内置函数:lambda、map、filter简单介绍
2017/11/16 Python
PyCharm 常用快捷键和设置方法
2017/12/20 Python
python如何对实例属性进行类型检查
2018/03/20 Python
Sanic框架流式传输操作示例
2018/07/18 Python
python正则表达式去除两个特殊字符间的内容方法
2018/12/24 Python
浅谈python函数调用返回两个或多个变量的方法
2019/01/23 Python
django迁移数据库错误问题解决
2019/07/29 Python
浅析python 字典嵌套
2020/09/29 Python
高中学生评语大全
2014/04/25 职场文书
供用电专业求职信
2014/07/07 职场文书
机关党总支领导班子整改方案
2014/09/20 职场文书
2015年五一劳动节活动总结
2015/02/09 职场文书
高中班主任工作总结(范文)
2019/08/20 职场文书