学习使用ExpressJS 4.0中的新Router
概述
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()创建链式路由
来源:https://segmentfault.com/a/1190000016909546
学习使用ExpressJS 4.0中的新Router的更多相关文章
- (数据科学学习手札73)盘点pandas 1.0.0中的新特性
本文对应脚本及数据已上传至我的Github仓库https://github.com/CNFeffery/DataScienceStudyNotes 1 简介 毫无疑问pandas已经成为基于Pytho ...
- Unity 4.0 中的新动画系统——MecAnim
分享一个文档资料,关于动画系统的,版本应该很老了,但是有借鉴意义的: Unity 4.0 已于 2012 年 11 月 15 日正式发布,Unity 每一次版本的提升,都给游戏开发者带来惊喜,这一次也 ...
- 在.Net Core 3.0中尝试新的System.Text.Json API
.NET Core 3.0提供了一个名为System.Text.Json的全新命名空间,它支持reader/writer,文档对象模型(DOM)和序列化程序.在此博客文章中,我将介绍它如何工作以及如何 ...
- WCF学习之旅—WCF4.0中的简化配置功能(十五)
六 WCF4.0中的简化配置功能 WCF4.0为了简化服务配置,提供了默认的终结点.绑定和服务行为.也就是说,在开发WCF服务程序的时候,即使我们不提供显示的 服务终结点,WCF框架也能为我们的服务提 ...
- C# 6.0中你不知道的新特性
为什么写? 今天去上班的公交上,有朋友在张队(张善友)的微信群里,发了一个介绍C# 6.0新特性的视频,视频7分钟,加上本人英语实在太low,整体看下来是一脸懵逼的. 下班回到家里,打开这个视频,把视 ...
- 【译】.NET Core 3.0 中的新变化
.NET Core 3.0 是 .NET Core 平台的下一主要版本.本文回顾了 .Net Core 发展历史,并展示了它是如何从基本支持 Web 和数据工作负载的版本 1,发展成为能够运行 Web ...
- [转]【译】.NET Core 3.0 中的新变化
.NET Core 3.0 是 .NET Core 平台的下一主要版本.本文回顾了 .Net Core 发展历史,并展示了它是如何从基本支持 Web 和数据工作负载的版本 1,发展成为能够运行 Web ...
- xcode 5.0中,新的开发者证书加载方式
按照先前从网上看到的参考,开通了开发者账号之后,要先在本地生成一个request文件,然后上传苹果开发者网站,然后在官网上生成一个证书.cer文件,拿这个文件在本地生成p12文件,然后就是一堆鸡零狗碎 ...
- Qt 5.0+ 中 connect 新语法与重载函数不兼容问题的解决方法,以及个人看法
Qt 5.0+ 版本提供了 connect 的新语法,相比之前的语法新语法可以提供编译期检查,使用也更方便.可是使用过程中发现一个小问题——当某个 signal 和成员函数是重载关系的时候,qmake ...
随机推荐
- OWASP Dependency-Check插件介绍及使用
1.Dependency-Check可以检查项目依赖包存在的已知.公开披露的漏洞.目前良好的支持Java和.NET:Ruby.Node.js.Python处于实验阶段:仅支持通过(autoconf a ...
- git 指令如何撤销一次merge
在使用git指令时难免会发生错误的merge的情况,那么如何在这种情况下回退到错误发生之前的情况? git reflog 指令显示历史的操作 4457e43 HEAD@{0}: reset: movi ...
- 转: Linux下使用java -jar运行可执行jar包的正确方式
from: http://codepub.cn/2016/05/11/The-correct-way-to-use-java-jar-run-an-executable-jar-package-un ...
- es6 - 模板
'use strict'; // es5 let name = 'mrs'; let qb = 20; function logs() { return 'goods!'; } let html = ...
- js学习总结--DOM2兼容处理重复问题
在解决this问题之后,只需要在每次往自定义属性和事件池当中添加事件的时候进行以下判断就好了,具体代码如下: /* bind:处理DOM2级事件绑定的兼容性问题(绑定方法) @parameter: c ...
- 利用JS最真实的模拟鼠标点击
为了破解永乐票务登录验证码问题 http://www.228.com.cn/auth/login?logout 当然,打码的过程自然依赖第三方平台,但问题是,哪怕平台给了你需要点击的(相对)坐标.你又 ...
- A和B是好友,他们经常在空闲时间聊天,A的空闲时间为[a1 ,b1 ],[a2 ,b2 ]..[ap ,bp ]。B的空闲时间是[c1 +t,d1 +t]..[cq +t,dq +t],这里t为B的起床时间。这些时间包括了边界点。B的起床时间为[l,r]的一个时刻。若一个起床时间能使两人在任意时刻聊天,那么这个时间就是合适的,问有多少个合适的起床时间?
// ConsoleApplication5.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" #include<vector> ...
- java和erlang之间的DES加解密
app登录,登录的密码要用DES加密,服务器是用erlang,客户端要同时支持多平台(Android.iOS).首先,Java端的DES加密的实现方式, 少说废话了,直接上代码,如下: public ...
- 07 redi sorder set结构及命令详解
zadd key score1 value1 score2 value2 .. 添加元素 redis 127.0.0.1:6379> zadd stu 18 lily 19 hmm 20 lil ...
- Android 开发小工具之:Tools 属性 (转)
Android 开发小工具之:Tools 属性 http://blog.chengyunfeng.com/?p=755#ixzz4apLZhfmi 今天来介绍一些 Android 开发过程中比较有用但 ...