学习使用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 相关文章推荐
基于jquery DOM写的类似微博发布的效果
Oct 20 Javascript
jQuery实现仿腾讯迷你首页选项卡效果代码
Sep 17 Javascript
ReactNative之键盘Keyboard的弹出与消失示例
Jul 11 Javascript
node.js express中app.param的用法详解
Jul 16 Javascript
基于vue监听滚动事件实现锚点链接平滑滚动的方法
Jan 17 Javascript
VUE 3D轮播图封装实现方法
Jul 03 Javascript
Vue实现底部侧边工具栏的实例代码
Sep 03 Javascript
小程序实现列表多个批量倒计时
Jan 29 Javascript
微信小程序如何获取用户头像和昵称
Sep 23 Javascript
js Math数学简单使用操作示例
Mar 13 Javascript
JS轮播图的实现方法2
Aug 25 Javascript
uniapp实现可滑动选项卡
Oct 21 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
解析php mysql 事务处理回滚操作(附实例)
2013/08/05 PHP
php计算程序运行时间的简单例子分享
2014/05/10 PHP
一个严格的PHP Session会话超时时间设置方法
2014/06/10 PHP
PHP实现批量生成App各种尺寸Logo
2015/03/19 PHP
PHP使用PHPexcel导入导出数据的方法
2015/11/14 PHP
PHP 下载文件时如何自动添加bom头及解释BOM头和去掉bom头的方法
2016/01/04 PHP
用JQuery 实现的自定义对话框
2007/03/24 Javascript
解决jQuery插件tipswindown与hintbox冲突
2010/11/05 Javascript
jQuery 借助插件Lavalamp实现导航条动态美化效果
2013/09/27 Javascript
form.submit()不能提交表单的原因分析
2014/10/23 Javascript
jQuery检测某个元素是否存在代码分享
2015/07/09 Javascript
提高jQuery性能优化的技巧
2015/08/03 Javascript
javascript运动效果实例总结(放大缩小、滑动淡入、滚动)
2016/01/08 Javascript
深入理解js函数的作用域与this指向
2016/05/28 Javascript
JS异步文件分片断点上传的实现思路
2016/12/25 Javascript
JavaScript正则替换HTML标签功能示例
2017/03/02 Javascript
vue父组件中获取子组件中的数据(实例讲解)
2017/09/27 Javascript
基于ionic实现下拉刷新功能
2018/05/10 Javascript
vue-cli history模式实现tomcat部署报404的解决方式
2019/09/06 Javascript
layui操作列按钮个数和文字颜色的判断实例
2019/09/11 Javascript
Python 随机生成中文验证码的实例代码
2013/03/20 Python
python自动12306抢票软件实现代码
2018/02/24 Python
python面试题小结附答案实例代码
2019/04/11 Python
Python全栈之列表数据类型详解
2019/10/01 Python
Python实现多线程下载脚本的示例代码
2020/04/03 Python
使用Python三角函数公式计算三角形的夹角案例
2020/04/15 Python
python时间time模块处理大全
2020/10/25 Python
英国一家专门出售品牌鞋子的网站:Allsole
2016/08/07 全球购物
英国评分最高的女性剃须刀订阅盒:FFS Beauty
2018/01/25 全球购物
蔻驰西班牙官网:COACH西班牙
2019/01/16 全球购物
linux面试题参考答案(5)
2016/11/05 面试题
“四风”问题自我剖析材料思想汇报
2014/09/23 职场文书
学生评语集锦
2015/01/04 职场文书
2016中考冲刺决心书
2015/09/22 职场文书
redis配置文件中常用配置详解
2021/04/14 Redis
使用pandas生成/读取csv文件的方法实例
2021/07/09 Python