学习使用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与js函数冲突的两种解决方法
Sep 09 Javascript
判断客户浏览器是否支持cookie的示例代码
Dec 23 Javascript
JavaScript String 对象常用方法详解
May 13 Javascript
Js+Ajax,Get和Post在使用上的区别小结
Jun 08 Javascript
浅谈Angularjs link和compile的使用区别
Oct 21 Javascript
node.js 和HTML5开发本地桌面应用程序
Dec 13 Javascript
jQuery插件Validation表单验证详解
May 26 jQuery
详解vue+webpack+express中间件接口使用
Jul 17 Javascript
详解关于element级联选择器数据回显问题
Feb 20 Javascript
Vue 处理表单input单行文本框的实例代码
May 09 Javascript
使vue实现jQuery调用的两种方法
May 12 jQuery
JavaScript实现鼠标经过表格某行时此行变色
Nov 20 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自动加载机制的深入分析
2013/06/08 PHP
实例分析PHP中PHPMailer发邮件
2017/12/13 PHP
php workerman定时任务的实现代码
2018/12/23 PHP
PHP解密支付宝小程序的加密数据、手机号的示例代码
2021/02/26 PHP
javascript中用星号表示预录入内容的实现代码
2011/01/08 Javascript
jquery validate poshytip 自定义样式
2012/11/26 Javascript
JavaScript实现的图像模糊算法代码分享
2014/04/22 Javascript
深入理解JavaScript编程中的同步与异步机制
2015/06/24 Javascript
原生JS实现拖拽图片效果
2020/08/27 Javascript
网页瀑布流布局jQuery实现代码
2016/10/21 Javascript
js图片轮播手动切换特效
2017/01/12 Javascript
微信小程序实现默认第一个选中变色效果
2018/07/17 Javascript
详解微信小程序canvas圆角矩形的绘制的方法
2018/08/22 Javascript
vue-cli 3.x 配置Axios(proxyTable)跨域代理方法
2018/09/19 Javascript
小试小程序云开发(小结)
2019/06/06 Javascript
layui使用button按钮 点击出现弹层 弹层中加载表单的实例
2019/09/04 Javascript
layui内置模块layim发送图片添加加载动画的方法
2019/09/23 Javascript
微信sdk实现禁止微信分享(使用原生php实现)
2019/11/15 Javascript
Vue开发中遇到的跨域问题及解决方法
2020/02/11 Javascript
Vue CLI4 Vue.config.js标准配置(最全注释)
2020/06/05 Javascript
javascript实现电商放大镜效果
2020/11/23 Javascript
解决pandas无法在pycharm中使用plot()方法显示图像的问题
2018/05/24 Python
基于Numpy.convolve使用Python实现滑动平均滤波的思路详解
2019/05/16 Python
Python进阶:生成器 懒人版本的迭代器详解
2019/06/29 Python
PyCharm-错误-找不到指定文件python.exe的解决方法
2019/07/01 Python
Python 序列化和反序列化库 MarshMallow 的用法实例代码
2020/02/25 Python
Python with语句用法原理详解
2020/07/03 Python
calendar在python3时间中常用函数举例详解
2020/11/18 Python
CSS3实现苹果手机解锁的字体闪亮效果示例
2021/01/05 HTML / CSS
详解如何获取localStorage最大存储大小的方法
2020/05/21 HTML / CSS
车工岗位职责
2013/11/26 职场文书
秋季运动会加油稿200字
2014/01/11 职场文书
你的创业计划书怎样才能打动风投
2014/02/06 职场文书
小学三八妇女节活动方案
2014/03/16 职场文书
详解CocosCreator项目结构机制
2021/04/14 Javascript
Golang 语言控制并发 Goroutine的方法
2021/06/30 Golang