学习使用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 this 和 $(this) 的区别
Aug 23 Javascript
在IE 浏览器中使用 jquery的fadeIn() 效果 英文字符字体加粗
Jun 02 Javascript
JavaScript在Android的WebView中parseInt函数转换不正确问题解决方法
Apr 25 Javascript
JavaScript中获取HTML元素值的三种方法
Jun 20 Javascript
javascript基本数据类型及类型检测常用方法小结
Dec 14 Javascript
js上传图片预览的实现方法
May 09 Javascript
JS创建Tag标签的方法详解
Jun 09 Javascript
通过js动态创建标签,并设置属性方法
Feb 24 Javascript
JavaScript原型链与继承操作实例总结
Aug 24 Javascript
highCharts提示框中显示当前时间的方法
Jan 18 Javascript
Vue.js使用axios动态获取response里的data数据操作
Sep 08 Javascript
解决vue项目打包上服务器显示404错误,本地没出错的问题
Nov 03 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
全国FM电台频率大全 - 2 天津市
2020/03/11 无线电
php下实现伪 url 的超简单方法[转]
2007/09/24 PHP
php数组生成html下拉列表的方法
2015/07/20 PHP
php中define用法实例
2015/07/30 PHP
PHP安装GeoIP扩展根据IP获取地理位置及计算距离的方法
2016/07/01 PHP
PHP入门教程之数组用法汇总(创建,删除,遍历,排序等)
2016/09/11 PHP
Laravel使用swoole实现websocket主动消息推送的方法介绍
2019/10/20 PHP
使用jQuery.wechat构建微信WEB应用
2014/10/09 Javascript
jQuery事件详解
2017/02/23 Javascript
nodejs个人博客开发第二步 入口文件
2017/04/12 NodeJs
JS使用插件cryptojs进行加密解密数据实例
2017/05/11 Javascript
简单实现js鼠标跟随效果
2020/08/02 Javascript
基于JavaScript实现瀑布流布局
2018/08/15 Javascript
Vue 组件封装 并使用 NPM 发布的教程
2018/09/30 Javascript
微信公众号平台接口开发 获取access_token过程解析
2019/08/14 Javascript
不刷新网页就能链接新的js文件方法总结
2020/03/01 Javascript
JavaScript面向对象核心知识与概念归纳整理
2020/05/09 Javascript
JS实现悬浮球只在一侧滑动并且是横屏状态下
2020/08/19 Javascript
在Python中执行系统命令的方法示例详解
2017/09/14 Python
浅析python的Lambda表达式
2019/02/27 Python
套娃式文件夹如何通过Python批量处理
2020/08/23 Python
CSS3中background-clip和background-origin的区别示例介绍
2014/03/10 HTML / CSS
css3动画效果小结(推荐)
2016/07/25 HTML / CSS
html5实现多文件的上传示例代码
2014/02/13 HTML / CSS
解释一下抽象方法和抽象类
2016/08/27 面试题
网站编辑求职信
2013/10/17 职场文书
计算机应用专业学生的自我评价分享
2013/11/03 职场文书
银行求职推荐信范文
2013/11/30 职场文书
部队领导证婚词
2014/01/12 职场文书
普通话演讲稿
2014/09/03 职场文书
企业党员个人自我评价
2014/09/20 职场文书
护士自荐信怎么写
2015/03/06 职场文书
2016优秀大学生个人事迹材料范文
2016/03/01 职场文书
vue中利用mqtt服务端实现即时通讯的步骤记录
2021/07/01 Vue.js
经典《舰娘》游改全新动画预告 预定11月开播
2022/04/01 日漫
Python可视化神器pyecharts之绘制箱形图
2022/07/07 Python