这篇文章主要介绍“Node express路由如何使用”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“Node express路由如何使用”文章能帮助大家解决问题。
路由是指如何定义应用的端点(
URIs)以及如何响应客户端的请求。
路由是由一个
URI、
HTTP请求(
GET、
POST等)和若干个句柄组成,它的结构如下:
app.METHOD(path, [callback...], callback)
app
是express
对象的一个实例METHOD
是一个HTTP
请求方法path
是服务器上的路径callback
是当路由匹配时要执行的函数
1、基础路由
先定义一个基础的路由:
const express = require("express"); // app对象 const app = express(); app.get("/", (req, res) => { res.send("匹配/"); });
上面的例子表示的是一个路径为
/的
GET请求路由,即当用户使用
GET请求访问
/时会执行
(req, res) =>{res.send("匹配/");}函数。
路由路径和请求方法一起定义了请求的端点:
// 匹配 / 路径的get请求 app.get("/", (req, res) => { res.send("匹配 / 路径的get请求"); }); // 匹配 / 路径的post请求 app.post("/", (req, res) => { res.send("匹配 / 路径的post请求"); }); // 匹配 / 路径的put请求 app.put("/", (req, res) => { res.send("匹配 / 路径的put请求"); }); // 匹配 / 路径的delete请求 app.delete("/", (req, res) => { res.send("匹配 / 路径的delete请求"); });
观察上面的路由你会发现它们的请求路径是一样的,只是请求方式不同,这是允许的,因为相同路径的请求只要请求方法不同最后就会进入到不同的处理函数中。
这种风格的写法称为RES Tful,在开发
API接口中比较推荐使用。
RES Tful特点包括:
1、每一个URI代表1种资源;
2、客户端使用GET、POST、PUT、DELETE4个表示操作方式的动词对服务端资源进行操作:GET用来获取资源,POST用来新建资源(也可以用于更新资源),PUT用来更新资源,DELETE用来删除资源;
3、通过操作资源的表现形式来操作资源;
4、资源的表现形式是XML或者HTML;
5、客户端与服务端之间的交互在请求之间是无状态的,从客户端到服务端的每个请求都必须包含理解请求所必需的信息。
2、路径匹配
express的路由可以进行模糊匹配,这是因为
express的路由路径可以是字符串、字符串模式或者正则表达式。
字符串匹配
当路径使用字符串时进行的就是普通的匹配,路径是什么就匹配什么:
// 匹配根路径的请求 app.get('/', function (req, res) { res.send('root'); }); // 匹配 /about 路径的请求 app.get('/about', function (req, res) { res.send('about'); });
字符串模式匹配
在字符串的基础上添加一些额外的语法(如下)称为字符串模式。
?
表示可选:id
表示使用id
字段占位+
表示可出现多次(至少一次)*
表示任意
使用字符串模式的路径:
// 匹配 /acd 和 /abcd:?前边的字符代表可选 app.get("/ab?cd", function (req, res) { res.send("ok"); }); // 匹配 /ab/*******::id代表占位,这个id是自定义的(你也可以写:aa,:bb等),之后能用来获取/ab/后的参数 app.get("/ab/:id", function (req, res) { res.send("/ab/*******"); }); // 匹配 /abcd,/abbcd,/abbbcd等,+号前的字符可以连续出现多个 app.get("/ab+cd", function (req, res) { res.send("/ab+cd"); }); // 匹配 /abcd,/abxcd,/abBIHIHIcd,/ab1456cd等,*号代表任意字符 app.get("/ab*cd", function (req, res) { res.send("/ab*cd"); }); // 匹配 /abe,/abcde,可以使用括号包裹多个字符形成一个整体 app.get("/ab(cd)?e", function (req, res) { res.send("/ab(cd)?e"); });
正则匹配
express路由匹配中最强大的一点就是它能够根据正则来进行匹配(虽然这在开发中用处不多)。
使用正则表达式的路由路径:
// 匹配任何路径中含有 a 的路径: app.get(/a/, function (req, res) { res.send("/a/"); }); // 匹配 butterfly、dragonfly,不匹配 butterflyman、dragonfly man等 app.get(/.*fly$/, function (req, res) { res.send("/.*fly$/"); });
3、处理函数
可以为请求处理提供多个回调函数,其行为类似 中间件。
唯一的区别是这些回调函数有可能调用 next('route')
或next('router')
方法而略过其他路由回调函数。
多函数
使用多个回调函数处理路由(记得指定
next对象):
// 直接添加多个回调函数 app.get( "/", (req, res, next) => { console.log("第一个执行"); next(); }, (req, res, next) => { console.log("第二个执行"); next(); // next('route') next中添加route参数时会跳过之后的回调函数 }, (req, res) => { console.log("最后一个执行"); // 返回数据内容 res.send("home"); } );
调用
next()就是意味着放行去执行下一个函数
注意:向客户端返回信息的操作(
res.send)要放到最后一个处理函数中,如果放到前面则会阻止后面处理函数的运行(这样的话,后面定义的处理函数有什么意义?),并且当
res.send与
next()处于一个处理函数中时会报错
函数数组
还可以以数组的形式添加回调函数:
const f1 = (req, res, next) => { console.log("第一个执行"); next(); }; const f2 = (req, res, next) => { console.log("第二个执行"); next(); }; const f3 = (req, res) => { console.log("最后一个执行"); res.send("login"); }; app.get("/login", [f1, f2, f3]);
混合使用
混合使用函数和函数数组处理路由:
const fn1 = function (req, res, next) { console.log("fn1"); next(); }; var fn2 = function (req, res, next) { console.log("fn2"); next(); }; app.get( "/about", [fn1, fn2], function (req, res, next) { console.log("fn3"); next(); }, function (req, res) { res.send("about"); } );
应用
可以利用该机制为路由定义前提条件,如果在现有路径上继续执行没有意义,则可将控制权交给剩下的路径。
例如在开发中经常使用到的
token验证,假如现在共有三个接口:
/login
用户登录的接口,不需要token
验证/home
只有token
验证通过才能访问/user
只有token
验证通过才能访问
这时我们就可以这样开发:
// 不需要token验证 app.get("/login", (req, res) => { res.send("登录"); }); // 验证token的函数(可插拔,可复用的中间件) const isToken = (req, res, next) => { // 验证token是否过期,isVaild代表token是否有效 // 一些操作 const isVaild = true; // 假设验证通过 if (isVaild) { // 验证通过了就调用next向下执行 console.log("token验证通过"); // 如果想要在回调函数之间传递数据,我们可以选择将数据挂载到res参数上 res.ailjx = "海底烧烤店ai"; next(); } else { // 返回错误 // 这里res.send后后面的回调函数就不会再执行了 res.send("token验证失败!"); } }; // 只有token有效时才生效的接口 app.get("/home", [isToken], (req, res) => { // 返回数据内容 // res.ailjx:获取验证token的函数在res上绑定的数据 res.send("home" + res.ailjx); }); app.get("/user", [isToken], (req, res) => { // 返回数据内容 res.send("user"); });
上面我们将验证
token的函数抽离了出去,之后在需要该函数的路由中直接引用即可,这就避免了我们需要在每个路由中都写一遍token验证的繁琐过程。
4、路由级中间件
上面我们定义的路由都是直接绑定到了
app对象上,这称为应用级中间件。
应用级中间件绑定到
app对象 使用
app.use()和
app.METHOD(), 其中,
METHOD是需要处理的
HTTP请求的方法,例如
get,
put,
post等等,全部小写。
当我们的路由过多时,这势必会变得难以维护,于是就出现了路由级中间件用来将我们的路由抽离出来,路由级中间件和应用级中间件一样,只是它绑定的对象为
express.Router()。
// apiRouter.js const express = require("express"); // router对象 const router = express.Router(); // 路由级别中间件:api路由 router.get("/home", (req, res) => { res.send({ list: [1, 2, 3, 4], }); }); router.get("/about", (req, res) => { res.send({ name: "ailjx", age: 18, }); }); // 导出 module.exports = router;
// server.js const express = require("express"); const app = express(); // 导入api路由 const apiRouter = require("./route/apiRouter"); // 使用app.use将路由挂载至应用 app.use(apiRouter); app.listen(3000, () => { console.log("start"); });
上面我们使用路由级中间件定义路由,之后通过模块化导入的形式将路由导入,再使用
app.use将路由挂载至应用,这种代码结构就使得整个项目变得更加容易维护。
在挂载路由时我们也可以指定一级路径:
// 如果use具有第一个路径参数,如下面的/api,则/api相当于是一级路径,apiRouter里的路径就相当于二级路径了 app.use("/api", apiRouter);
这样挂载后的路由访问时就需要加上
/api,如:
/api/home
/api/about