diff --git a/files/zh-cn/learn/server-side/express_nodejs/routes/index.md b/files/zh-cn/learn/server-side/express_nodejs/routes/index.md
index 866dfd8e9fed7b..2c9792435fcd26 100644
--- a/files/zh-cn/learn/server-side/express_nodejs/routes/index.md
+++ b/files/zh-cn/learn/server-side/express_nodejs/routes/index.md
@@ -2,12 +2,12 @@
title: Express 教程 4:路由和控制器
slug: Learn/Server-side/Express_Nodejs/routes
l10n:
- sourceCommit: e39ad1510b9794cd393dfc6a48e3a3d3d7a4c732
+ sourceCommit: 3dd00b3b77e2e79c7d92f0b6c4f4665d54500a0e
---
{{LearnSidebar}}{{PreviousMenuNext("Learn/Server-side/Express_Nodejs/mongoose", "Learn/Server-side/Express_Nodejs/Displaying_data", "Learn/Server-side/Express_Nodejs")}}
-在本教程中,我们将为 [LocalLibrary](/zh-CN/docs/Learn/Server-side/Express_Nodejs/Tutorial_local_library_website) 网站最终需要的所有资源端点设置具有 "虚拟 "处理函数的路由(URL 处理代码)。完成后,我们就有了路由处理代码的模块化结构,可以在接下来的文章中使用真正的处理函数对其进行扩展。此外,我们还将真正了解如何使用 Express 创建模块化路由!
+在本教程中,我们将为 [LocalLibrary](/zh-CN/docs/Learn/Server-side/Express_Nodejs/Tutorial_local_library_website) 网站最终需要的所有资源端点设置具有"虚拟"处理函数的路由(URL 处理器)。完成后,我们就有了路由处理代码的模块化结构,可以在接下来的文章中使用真正的处理器对其进行扩展。此外,我们还将真正了解如何使用 Express 创建模块化路由!
@@ -17,9 +17,9 @@ l10n:
回顾
Express/Node 入门。完成本教程之前小节(。完成本教程之前小节(包括 Express 教程 3:使用数据库 (Mongoose)Express 教程 3:使用数据库(Mongoose))。
@@ -32,31 +32,32 @@ l10n:
## 概览
-[上节](/zh-CN/docs/Learn/Server-side/Express_Nodejs/mongoose) 定义了与数据库交互的 _Mongoose_ 模型,使用一个(独立)脚本创建了一些初始记录。现在可以编写代码来向用户展示这些信息。首先要确定页面中应显示哪些信息,然后定义适当的 URL 来返回这些资源。随后应创建路由(URL 处理器)和视图(模板)来显示这些页面。
+[上节](/zh-CN/docs/Learn/Server-side/Express_Nodejs/mongoose) 我们定义了与数据库交互的 _Mongoose_ 模型,并使用一个(独立)脚本创建了一些初始记录。现在可以编写代码来向用户展示这些信息。我们首先要确定页面中应显示哪些信息,然后定义适当的 URL 来返回这些资源。随后要创建路由(URL 处理器)和视图(模板)来显示这些页面。
-下图展示了 HTTP 请求/响应处理的主数据流和需要实现的行为。图中除视图(View)和路由(Route)外,还展示了控制器(Controller),它们是实际的请求处理函数,与路由请求代码是分开的。
+下图展示了 HTTP 请求/响应处理的主数据流和需要实现的行为。图中除视图(View)和路由(Route)外,还展示了控制器(Controller),即与路由请求代码是分开的实际的请求处理函数。
因为我们已经创建好了模型,我们接下来需要创建的是:
-- 路由:把需要支持的请求(以及请求 URL 中包含的任何信息)转发到适当的控制器函数。
+- “路由”:把需要支持的请求(以及请求 URL 中包含的任何信息)转发到适当的控制器函数。
- 控制器:从模型中获取请求的数据,创建一个 HTML 页面显示出数据,并将页面返回给用户,以便在浏览器中查看。
- 视图(模板):供控制器用来渲染数据。
![MVC Express 服务器的主要数据流图:“路由”接收发送到 Express 服务器的 HTTP 请求,并将其转发给相应的“控制器”功能。控制器从模型中读取和写入数据。模型连接到数据库,为服务器提供数据访问。控制器使用“视图”(也称为模板)来呈现数据。控制器将 HTML HTTP 响应作为 HTTP 响应发送回客户端。](mvc_express.png)
-因此我们需要页面来显示藏书、藏书种类、作者、藏书副本的列表和详细信息,还需要页面来创建、更新和删除记录。这些内容对于本节来说不算少,因此本节将主要集中在路由和控制器设置。本节编写的这些函数都只有框架,后续章节再扩展控制器方法,以使用模型数据。
+因此我们最终需要显示图书、图书种类、作者、图书副本的列表和详细信息的页面,还需要页面来创建、更新和删除记录。这些内容对于本节来说不算少,因此本节将主要集中在路由和控制器设置。本节编写的这些函数都只有框架,而会后续章节再扩展控制器方法以使用模型数据。
-第一段提供了 Express 的 [Router](http://expressjs.com/en/4x/api.html#router) 中间件的“入门”知识。后续设置 LocalLibrary 路由时将用到这些知识。
+第一小节提供了 Express 的 [Router](http://expressjs.com/en/4x/api.html#router) 中间件的“入门”知识。后续设置 LocalLibrary 路由时我们将用到这些知识。
## 路由入门
路由是一段 Express 代码,它将 HTTP 动词(`GET`、`POST`、`PUT`、`DELETE` 等)、URL 路径/模式和处理函数三者关联起来。
-创建路由有几种方法。本教程将使 [`express.Router`](http://expressjs.com/en/guide/routing.html#express-router) 中间件,因为使用它可以将站点特定部分的路由处理程序打包,并使用通用路由前缀访问它们。我们会将所有与图书馆有关的路由保存在 `catalog` 模块中,在添加处理帐户或其他功能的路由时,可以分开保存。
+创建路由有多种方法。在本教程中,我们将使用 [`express.Router`](https://expressjs.com/en/guide/routing.html#express-router) 中间件,因为它允许我们将网站特定部分的路由处理程序分组在一起并使用共同的路由前缀访问它们。我们将把所有与图书馆相关的路由保存在一个“目录”模块中,如果我们添加了用于处理用户账户或其他功能的路由,可以将它们单独分组。
-> **备注:** [Express 简介 > 创建路由处理程序](/zh-CN/docs/Learn/Server-side/Express_Nodejs/Introduction#创建路由处理器(route_handler)) 简要讨论了 Express 应用的路由机制。使用 `Router` 可以保证更好的模块化(下文所述),且用法与直接在 Express 应用对象定义路由非常类似。
+> [!NOTE]
+> 我们在 [Express 简介 > 创建路由处理程序](/zh-CN/docs/Learn/Server-side/Express_Nodejs/Introduction#创建路由处理器(route_handler))中简要讨论了 Express 应用的路由机制。使用 _Router_ 可以保证更好的模块化(下文所述),且用法与直接在 _Express 应用对象_定义路由非常类似。
-本段以下内容介绍使用 `Router` 定义路由的方法。
+本小节的剩余部分内容将介绍使用 `Router` 定义路由的方法。
### 定义和使用单独的路由模块
@@ -109,9 +110,9 @@ router.get("/about", (req, res) => {
该回调有三个参数(通常命名为:`req`、`res`、`next`),分别是:HTTP 请求对象、HTTP 响应、中间件链中的下一个函数。
> [!NOTE]
-> 路由函数就是 [Express 中间件](/zh-CN/docs/Learn/Server-side/Express_Nodejs/Introduction#Using_middleware),这意味着它们必须(通过响应)结束请求,否则必须调用链中的 `next` 函数。上述示例使用`send()` 完成了请求,所以没有使用 `next` 参数(参数表中将其省略)。
+> 路由函数就是 [Express 中间件](/zh-CN/docs/Learn/Server-side/Express_Nodejs/Introduction#使用中间件),这意味着它们要么(通过响应)结束请求,要么调用链中的 `next` 函数。在上述示例中,我们使用 `send()` 完成了请求,因而没有再用上 `next` 参数(参数表中将其省略)。
>
-> 上述路由函数只需要一个回调,可以根据需要指定任意数量的回调参数,或一个回调函数数组。每个函数都将加入中间件链,并且将按添加顺序调用(若有回调完成请求则中止当前周期)。
+> 上述路由函数只需要一个回调。我们可以根据需要指定任意数量的回调参数或一个回调函数数组。每个函数都将加入中间件链,并且将按添加顺序调用(若有回调完成请求则中止当前周期)。
此处的回调对响应对象调用 [`send()`](https://expressjs.com/en/4x/api.html#res.send),当收到带有路径('`/about'`)的 GET 请求时将返回字符串“关于此维基”。还有许多其他可以结束请求/响应周期 [响应方法](https://expressjs.com/en/guide/routing.html#response-methods),例如,可调用 [`res.json()`](https://expressjs.com/en/4x/api.html#res.json) 来发送 JSON 响应,或调用 [`res.sendFile()`](https://expressjs.com/en/4x/api.html#res.sendFile) 来发送文件。构建 LocalLibrary 最常使用的响应方法是 [render()](https://expressjs.com/en/4x/api.html#res.render),它使用模板和数据创建并返回 HTML 文件。我们将在后续章节进一步讨论。
@@ -119,7 +120,7 @@ router.get("/about", (req, res) => {
上面的示例使用 `Router.get()` 方法来响应特定路径的 HTTP GET 请求。
-`Router` 还为所有其他 HTTP 动词提供路由方法,大都用法相同:`post()`, `put()`, `delete()`, `options()`, `trace()`, `copy()`, `lock()`, `mkcol()`, `move()`, `purge()`, `propfind()`, `proppatch()`, `unlock()`, `report()`, `mkactivity()`, `checkout()`, `merge()`, `m-search()`, `notify()`, `subscribe()`, `unsubscribe()`, `patch()`, `search()`, 和 `connect()`。
+`Router` 还为所有其他 HTTP 动词提供路由方法,大都用法相同:`post()`、`put()`、`delete()`、`options()`、`trace()`、`copy()`、`lock()`、`mkcol()`、`move()`、`purge()`、`propfind()`、`proppatch()`、`unlock()`、`report()`、`mkactivity()`、`checkout()`、`merge()`、`m-search()`、`notify()`、`subscribe()`、`unsubscribe()`、`patch()`、`search()` 和 `connect()`。
比如下方代码与上方 `/about` 路由行为一致,但只响应 HTTP POST 请求。
@@ -131,7 +132,7 @@ router.post("/about", (req, res) => {
### 路由路径
-路由路径用于定义可请求的端点。之前示例中路径都是字符串,并且必须精确写为“/”、“/about”、“/book”,等等。
+路由路径用于定义可请求的端点。之前示例中路径都是字符串,并且必须精确写作:“/”、“/about”、“/book”诸如此类。
路由路径也可以是字符串模式(String Pattern)。可用部分*正则表达式语法*来定义端点的模式。以下是所涉及的正则表达式(注意,连字符(`-`)和点(`.`)在字符串路径中解释为字面量,不能做为正则表达式):
@@ -153,9 +154,9 @@ app.get(/.*fish$/, (req, res) => {
### 路由参数
-路径参数是*命名的 URL 段*,用于捕获在 URL 中的位置指定的值。命名段以冒号为前缀,然后是名称(例如 `/:your_parameter_name/`。捕获的值保存在 `req.params` 对象中,键即参数名(例如 `req.params.your_parameter_name`)。
+路径参数是*命名的 URL 片段*,用于捕获在 URL 中的位置指定的值。命名段以冒号为前缀并紧接着名称(如 `/:your_parameter_name/`)。捕获的值保存在 `req.params` 对象中,其中参数名对应对象的键(例如 `req.params.your_parameter_name`)。
-举例说,一个包含用户和藏书信息的 URL:`http://localhost:3000/users/34/books/8989`。我们可以这样提取信息(使用 `userId` 和 `bookId` 路径参数):
+比如,我们考虑一个包含用户和图书信息的 URL `http://localhost:3000/users/34/books/8989`。我们可以这样提取信息(使用 `userId` 和 `bookId` 路径参数):
```js
app.get("/users/:userId/books/:bookId", (req, res) => {
@@ -170,7 +171,7 @@ app.get("/users/:userId/books/:bookId", (req, res) => {
> [!NOTE]
> URL `/book/create` 会匹配 `/book/:bookId` 这样的路由(将提取值为'`create`' 的 '`bookId`')。第一个与传入 URL 相匹配的路由会被使用,因此 `/book/create` 的路由处理器必须定义在 `/book/:bookId` 路由之前,才能妥善处理。
-以上就是使用路由所有的预备知识。Express 文档中还能找到更多信息:[基础路由](http://expressjs.com/en/starter/basic-routing.html) 和 [路由指南](http://expressjs.com/en/guide/routing.html)。以下是 LocalLibrary 路由和控制器的设置过程。
+以上就是使用路由所有的预备知识。Express 文档中还能找到更多信息:[基础路由](http://expressjs.com/en/starter/basic-routing.html)和[路由指南](http://expressjs.com/en/guide/routing.html)。以下是 LocalLibrary 路由和控制器的设置过程。
### 处理路由函数中的错误
@@ -196,7 +197,8 @@ router.get("/about", (req, res, next) => {
为了使框架正确处理异常,这些异常必须被捕获,然后将其作为错误转发,如上一节所示。
-> **备注:** 目前处于测试阶段的 Express 5 有望处理 JavaScript 异常。
+> [!NOTE]
+> 目前处于测试阶段的 Express 5 有望能处理 JavaScript 异常。
在上一节中的简单示例中,`About.find().exec()` 是返回 Promise 的数据库查询,我们可以在 [`try...catch`](/zh-CN/docs/Web/JavaScript/Reference/Statements/try...catch) 块内编写路由函数,如下所示:
@@ -211,7 +213,7 @@ exports.get("/about", async function (req, res, next) {
});
```
-每个函数都需要添加大量的样板代码。在本教程中,我们将使用 [express-async-handler](https://www.npmjs.com/package/express-async-handler) 模块。它定义了一个包装器函数,隐藏了 `try...catch` 块和用于转发错误的代码。现在,相同的示例非常简单,因为我们只需要为假设成功的情况编写代码:
+每个函数都需要添加大量的样板代码。在本教程中,我们将使用 [express-async-handler](https://www.npmjs.com/package/express-async-handler) 模块。它定义了一个包装器函数,隐藏了 `try...catch` 块和用于转发错误的代码。现在,相同的示例将变得非常简单,因为我们只需要为假设成功的情况编写代码:
```js
// 导入模块
@@ -231,7 +233,7 @@ exports.get(
以下是站点页面的完整 URL 列表,其中 _object_ 是模型名称(`book`、`bookinstance`、`genre`、`author`),_objects_ 是一组模型,_id_ 是每个 Mongoose 模型实例默认的标识字段(`_id`)。
- `catalog/`:主页。
-- `catalog//`:模型(藏书、藏书副本、藏书种类、作者)的完整列表(例如 `/catalog/books/`、`/catalog/genres/` 等)
+- `catalog//`:模型(图书、图书副本、图书种类、作者)的完整列表(例如 `/catalog/books/`、`/catalog/genres/` 等)
- `catalog/