Skip to content

路由

Express 支持与所有 HTTP 请求方法相对应的方法:getpost等等

js
const app = require('express')();

app.all

有一种特殊的路由方法,app.all() 用于在路径上为 所有HTTP 请求方法加载中间件函数。例如,对于路由 “/secret”的请求,无论是使用 GET、POST、PUT、DELETE 还是http 模块中支持的任何其他 HTTP 请求方法,都会执行以下处理程序

js
app.all('/secret', function (req, res, next) {
  console.log('访问秘密部分 ...')
  next() // 将控制权传递给下一个处理程序
})

路由路径

路由路径可以是字符串字符串模式正则表达式

字符?、+、*和()是其正则表达式对应字符的子集。连字符 ( -) 和点 ( .) 由基于字符串的路径按字面意思解释。

如果需要在路径字符串中使用美元符号 $,请将其转义并括在([和中])。例如,“/data/$book” 处请求的路径字符串将是 “/data/([\$])book”

Express 使用 path-to-regexp 来匹配路由路径;请参阅 path-to-regexp 文档,了解定义路由路径的所有可能性

以下是一些基于字符串模式的路由路径的示例。

该路线路径将匹配 acdabcd

js
app.get('/ab?cd', function (req, res) {
  res.send('ab?cd')
})

该路由路径将匹配 abcdabbcdabbbcd 等等。

js
app.get('/ab+cd', function (req, res) {
  res.send('ab+cd')
})

该路由路径将匹配 abcdabxcdabRANDOMcdab123cd 等等。

js
app.get('/ab*cd', function (req, res) {
  res.send('ab*cd')
})

该路线路径将匹配 /abe/abcde

js
app.get('/ab(cd)?e', function (req, res) {
  res.send('ab(cd)?e')
})

基于正则表达式的路由路径示例:

此路线路径将匹配其中带有“a”的任何内容。

js
app.get(/a/, function (req, res) {
  res.send('/a/')
})

此路由路径将匹配 butterflydragonfly,但不匹配 butterflymandragonflyman 等等。

js
app.get(/.*fly$/, function (req, res) {
  res.send('/.*fly$/')
})

路由参数

路由参数是命名的 URL 段,用于捕获 URL 中其位置指定的值。捕获的值将填充到对象中 req.params,并使用路径中指定的路由参数名称作为其各自的键。

要定义带有路由参数的路由,只需在路由路径中指定路由参数,如下所示

js
// Request URL: http://localhost:3000/users/34/books/8989
app.get('/users/:userId/books/:bookId', function (req, res) {
  res.send(req.params)
})
// req.params: { "userId": "34", "bookId": "8989" }

路由参数的名称必须由“单词字符”组成([A-Za-z0-9_])

由于连字符 ( -) 和点 ( .) 按字面意思解释,因此它们可以与路由参数一起使用,如下所示

js
Route path: /flights/:from-:to
Request URL: http://localhost:3000/flights/LAX-SFO
req.params: { "from": "LAX", "to": "SFO" }
js
Route path: /plantae/:genus.:species
Request URL: http://localhost:3000/plantae/Prunus.persica
req.params: { "genus": "Prunus", "species": "persica" }

为了更好地控制路由参数可以匹配的精确字符串,你可以在括号 () 中附加一个正则表达式:

js
Route path: /user/:userId(\d+)
Request URL: http://localhost:3000/user/42
req.params: {"userId": "42"}

由于正则表达式通常是文字字符串的一部分,因此请务必使用\额外的反斜杠转义所有字符,例如\\d+。

路由处理程序

您可以提供多个回调函数,这些回调函数的作用类似于中间件,用于处理请求

路由处理程序可以采用函数 函数数组两者的组合的形式,如以下示例所示。

一个路由可以有多个回调函数处理(请确保指定对象next)。例如:

js
app.get('/example/b', function (req, res, next) {
  console.log('响应将由下一个函数发送 ...')
  next()
}, function (req, res) {
  res.send('Hello from B!')
})

一组回调函数可以处理一个路由。例如:

js
var cb0 = function (req, res, next) {
  console.log('CB0')
  next()
}

var cb1 = function (req, res, next) {
  console.log('CB1')
  next()
}

var cb2 = function (req, res) {
  res.send('Hello from C!')
}

app.get('/example/c', [cb0, cb1, cb2])

独立函数和函数数组的组合可以处理路由。例如:

js
var cb0 = function (req, res, next) {
  console.log('CB0')
  next()
}

var cb1 = function (req, res, next) {
  console.log('CB1')
  next()
}

app.get('/example/d', [cb0, cb1], function (req, res, next) {
  console.log('the response will be sent by the next function ...')
  next()
}, function (req, res) {
  res.send('Hello from D!')
})

响应方法

方法说明
res.download()提示要下载的文件
res.end()结束响应
res.json()发送 JSON 响应
res.jsonp()发送具有 JSONP 支持的 JSON 响应
res.redirect()重定向请求
res.render()渲染视图模板
res.send()发送各种类型的回应
res.sendFile()以八位字节流的形式发送文件
res.sendStatus()设置响应状态代码并将其字符串表示形式作为响应主体发送

app.route()

您可以使用 为路由路径创建可链接的路由处理程序 app.route()。由于路径是在单个位置指定的,因此创建模块化路由很有用,还可以减少冗余和拼写错误

下面是使用 定义的 链式路由 处理程序的示例 app.route()

js
app.route('/book')
  .get(function (req, res) {
    res.send('Get a random book')
  })
  .post(function (req, res) {
    res.send('Add a book')
  })
  .put(function (req, res) {
    res.send('Update the book')
  })

express.Router

使用 express.Router 类创建模块化、可安装的路由处理程序。 Router 实例是一个完整的中间件和路由系统;因此,它通常被称为 “迷你应用程序”

下面的示例创建一个路由器作为模块,在其中加载一个中间件功能,定义一些路由,并将路由器模块挂载在主应用程序的路径上。

在 app 目录下创建一个名为 birds.js 的 router 文件,内容如下:

js
var express = require('express')
var router = express.Router()

// 特定于此路由器的中间件
router.use(function timeLog (req, res, next) {
  console.log('Time: ', Date.now())
  next()
})
// define the home page route
router.get('/', function (req, res) {
  res.send('Birds home page')
})
// define the about route
router.get('/about', function (req, res) {
  res.send('About birds')
})

module.exports = router

然后,在应用程序中加载路由器模块:

js
var birds = require('./birds')

// ...

app.use('/birds', birds)

该应用程序现在将能够处理对 /birds/birds/about 的请求,以及调用 timeLog 特定于路由的中间件函数。

Released under the MIT License.