路由基本认知
设置基本路由
在了解了使用原生设置路由之后,接下来我们需要更进一步,使用express框架设置路由,以下是设置简单路由的基本步骤:
javascript
//1、引入express模块
const express = require('express');
//创建服务器实例
const app = express();
//创建监听端口
const port = 3000;
// 定义一个 GET 路由
app.get('/', (req, res) => {
res.send('Hello, World!');
});
// 定义一个 POST 路由
app.post('/submit', (req, res) => {
res.send('Form submitted!');
});
// 启动服务器
app.listen(port, () => {
console.log(`Server is running on http://localhost:${port}`);
});
当客户端发出"GET" 和 "POST"请求,如果请求根路径('/'),服务器返回"Hello World!",对于POST请求,请求路径为'/submit'时,服务器在3000端口返回对应路由信息。
路由参数
什么是路由参数
路由参数是URL路径中的动态部分,通常传递一些变量值,例如以下路由中:
javascript
app.get('/users/:userId', (req, res) => {
const userId = req.params.userId;
res.send(`User ID is ${userId}`);
});
:userId
是一个路由参数,表示 URL 路径中的动态部分。- 当客户端访问
/users/123
时,req.params.userId
的值就是"123"
如何获取路由参数 :req.params和req.query
req.params
Express 允许我们从前端发送的请求的URL中提取参数,并且通过req.params (是一个包含所有 从URL路径中提取的路由参数的对象)
获取前端发送的参数值,例如:
ini
app.get('/users/:userId/posts/:postId', (req, res) => {
const userId = req.params.userId;
const postId = req.params.postId;
res.send(`User ID: ${userId}, Post ID: ${postId}`);
});
如果客户端访问 /users/123/posts/456
,req.params
的值将是:
css
{
userId:"123",
postId:"456"
}
req.query
req.query用于获取URL查询字符串中的参数,
如 (/users?name=John&age=30
),下例:
javascript
app.get('/search', (req, res) => {
const query = req.query.q;
res.send(`Search query: ${query}`);
});
-
如果客户端访问
/search?q=express
,req.query.q
的值将是"express"
。
路由中间件
什么是中间件
中间件是一个函数,它可以访问请求对象 (req
)、响应对象 (res
) 和 next
函数。其主要作用是:
-
执行某些逻辑(如验证、日志记录等)。
-
修改请求或响应对象。
-
决定是否继续执行后续的中间件或路由处理函数。
-----------------看到这儿感觉是个提示器或校验器?我觉得前端发送请求后控制台中的请求反馈提示算是一个中间件?接着往下看看吧
中间件类型
在 Express 中,中间件可以分为以下几种类型:
- 应用级中间件 :绑定到
app
实例上,对所有请求生效。 - 路由级中间件:绑定到特定的路由上,只对该路由生效。
- 错误处理中间件:专门用于处理错误。
- 内置中间件 :Express 自带的中间件,如
express.json()
。 - 第三方中间件 :通过 npm 安装的中间件,如
body-parser
中间件的使用
接下来我们进入一个简单中间件的创建使用:
javascript
const app = express();
const port = 3000;
// 定义一个中间件函数
const logRequest = (req, res, next) => {
console.log(`Request URL: ${req.url}, Method: ${req.method}`);
next(); // 调用 next() 继续执行后续的中间件或路由处理函数
};
// 将中间件应用到特定路由
app.get('/users', logRequest, (req, res) => {
res.send('User list');
});
// 启动服务器
app.listen(port, () => {
console.log(`Server is running on http://localhost:${port}`);
});
上述logRequest中间件实现了记录请求信息,并且通过调用next()函数来执行中间件,得出的结果在终端中成功显示:
错误处理中间件
错误处理中间件专门用于捕获和处理错误 。它需要接收四个参数:err
, req
, res
, next
。例如:
javascript
app.use((err, req, res, next) => {
console.error(err.stack);
res.status(500).send('Something went wrong!');
});
中间件代码的解析
-
app.use() :
app.use()
是 Express 中用于注册中间件的方法。- 它可以用于注册全局中间件或路由级中间件。
- 在这里,它注册了一个错误处理中间件。
-
参数 (err, req, res, next) :
- 错误处理中间件有 4 个参数 ,分别是
err
、req
、res
和next
。 - 与其他中间件(3 个参数:
req
、res
、next
)不同,错误处理中间件的第一个参数是err
,表示捕获到的错误对象。
- 错误处理中间件有 4 个参数 ,分别是
-
err:
err
是捕获到的错误对象,通常由其他中间件或路由处理函数通过next(err)
传递过来。- 它包含了错误的详细信息,例如错误消息、堆栈信息等。
-
console.error(err.stack) :
err.stack
是错误对象的堆栈信息,包含了错误发生的具体位置和调用链。console.error()
将错误堆栈信息输出到控制台,方便开发者调试。
-
res.status(500).send('Something went wrong!') :
res.status(500)
设置 HTTP 响应状态码为 500(服务器内部错误)。res.send('Something went wrong!')
向客户端发送一条简单的错误消息。- 这样,客户端会收到一个 500 错误响应,并显示 "Something went wrong!"。
在程序中任何地方调用next(err) 时,都会使用错误处理中间件
路由分组
什么是路由分组
路由分组是指将一组相关的路由(如 /users
、/users/:id
等)组织在一起,形成一个独立的路由模块
示例:
假设有一个用户相关的路由组,单独放在routes/users.js
文件里:
javascript
// routes/users.js
const express = require('express');
const router = express.Router();
// 定义用户相关的路由
router.get('/', (req, res) => {
res.send('User list');
});
router.get('/:id', (req, res) => {
const userId = req.params.id;
res.send(`User ID: ${userId}`);
});
router.post('/', (req, res) => {
res.send('Create a new user');
});
module.exports = router;
在主应用中挂载路由分组
ini
// app.js
const express = require('express');
const app = express();
const userRoutes = require('./routes/users');
// 将用户路由分组挂载到 /users 路径
app.use('/users', userRoutes);
// 启动服务器
const port = 3000;
app.listen(port, () => {
console.log(`Server is running on http://localhost:${port}`);
});
3、运行结果
- 访问
[http://localhost:3000/users](http://localhost:3000/users)
,返回 "User list"。 - 访问
[http://localhost:3000/users/123](http://localhost:3000/users/123)
,返回 "User ID: 123"。 - 发送 POST 请求到
[http://localhost:3000/users](http://localhost:3000/users)
,返回 "Create a new user"。
路由分组的优点
- 模块化:将相关路由组织在一起,便于维护和扩展。
- 代码复用:可以将路由分组模块化,并在多个应用中复用。
- 路径前缀:使用
app.use('/users', router)
可以为路由分组添加统一的前缀,避免重复书写路径。 - 中间件隔离:可以为不同的路由分组应用不同的中间件,实现更细粒度的控制。