Express文档翻译-- Routing

原文链接:http://www.expressjs.com.cn/guide/routing.html

路由

路由是指应用程序的终端(URIs)如何响应客户端请求。有关路由的介绍,请参见基本路由

您可以使用Express的app对象的方法定义路由,它相当于HTTP方法。例如,app.get()处理get请求,app.post()处理post请求。有关完整列表,请参见app.METHOD。您还可以使用app.all()处理所有HTTP方法,使用app.use()指定中间件作为回调函数(有关详细信息,请参见使用中间件)。

这些路由方法指定当应用程序接收到对指定路由(终端)和HTTP方法的请求时,调用的回调函数(有时称为“处理器函数”)。换句话说,应用程序“监听”与指定路由和方法匹配的请求,当检测到匹配时,它调用指定的回调函数。

实际上,路由方法可以有多个回调函数作为参数。对于多个回调函数,重要的是向回调函数提供next作为参数,然后在函数体中调用next()以将控制权移交给下一个回调。

下面的代码是一个非常基本的路由示例。

var express = require('express')
var app = express()

// respond with "hello world" when a GET request is made to the homepage
app.get('/', function (req, res) {
  res.send('hello world')
})

路由方法(Route methods)

一个路由方法从其中一个HTTP方法派生,并附加到一个Express类的实例。

下面的代码是一个路由示例,这个路由为get和post方法定义到应用程序根目录。

// GET method route
app.get('/', function (req, res) {
  res.send('GET request to the homepage')
})

// POST method route
app.post('/', function (req, res) {
  res.send('POST request to the homepage')
})

Express支持对应于所有HTTP请求方法的方法:get、post等。有关完整列表,请参见app.METHOD

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

app.all('/secret', function (req, res, next) {
  console.log('Accessing the secret section ...')
  next() // pass control to the next handler
})

路由路径(Route paths)

路由路径与请求方法相结合,定义了可以发出请求的端点。路由路径可以是字符串、字符串模式或正则表达式。

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

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

注意:
Express使用 path-to-regexp来匹配路由路径;有关定义路由路径的所有可能性,请参阅 path-to-regexp文档。Express Route Tester是一个测试基本Express路由的简便工具,尽管它不支持模式匹配。

查询字符串不是路由路径的一部分。

  1. 下面是一些基于字符串的路由路径示例。
// 此路由路径将匹配对根路由'/'的请求
app.get('/', function (req, res) {
  res.send('root')
})
// 此路由路径将匹配对'/about'的请求
app.get('/about', function (req, res) {
  res.send('about')
})
// 此路由路径将匹配对'/random.text'的请求
app.get('/random.text', function (req, res) {
  res.send('random.text')
})
  1. 下面是一些基于字符串模式的路由路径示例。
// 此路由路径将匹配 'acd'和'abcd'
app.get('/random.text', function (req, res) {
  res.send('random.text')
})
// 此路由路径将匹配 'abcd'、' abbcd'、' abbbcd'等
app.get('/random.text', function (req, res) {
  res.send('random.text')
})
// 此路由路径将匹配 'abcd'、'abxcd'、'abRANDOMcd'、'ab123cd'等
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')
})
  1. 基于正则表达式的路由路径示例:
// 此路径将与任何有一个'a'的字符串匹配
app.get(/a/, function (req, res) {
  res.send('/a/')
})
// 此路径将匹配'butterfly'和'dragonfly',但不匹配'butterflyman'、'dragonflyman'等。
app.get(/.*fly$/, function (req, res) {
  res.send('/.*fly$/')
})

路由参数(Route parameters)

路由参数是命名的URL片段,用于捕获在其URL中某个位置指定的值。捕获的值被添加在req.params对象中,路径中指定的路由参数的名称作为它们各自的键。

Route path:/users/:userId/books/:bookId
Request URL: http://localhost:3000/users/34/books/8989
req.params:{ "userId": "34", "bookId": "8989" }

要使用路由参数定义路由,只需在路由路径中指定路由参数,如下所示。

app.get('/users/:userId/books/:bookId', function (req, res) {
  res.send(req.params)
})

注意
路由参数的名称必须由字符[A-ZA-Z0-9_]组成。

由于连字符-和点字符.是按字面意义解释的,因此它们可以和路由参数一起使用。如下

Route path: /flights/:from-:to
Request URL: http://localhost:3000/flights/LAX-SFO
req.params: { "from": "LAX", "to": "SFO" }

Route path: /plantae/:genus.:species
Request URL: http://localhost:3000/plantae/Prunus.persica
req.params: { "genus": "Prunus", "species": "persica" }

若要对路由参数可以匹配的确切字符串拥有更多控制权,可以在括号()中追加正则表达式,如下:

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

注意:

因为正则表达式通常是文本字符串的一部分,所以一定要用附加的反斜杠\转义任何'\'字符,例如 \\d+

在express 4.x中,正则表达式中的*字符不以常规的方式解释,作为解决方法,使用{0,},而不是*。这可能会在 Express 5中修正。

路由处理器(Route handlers)

您可以提供多个回调函数,它们的行为类似于处理请求的中间件。唯一的例外是这些回调函数可能调用next('route')来绕过剩余的路由回调。您可以使用此机制对一个路由强制施加前提条件,然后在没有理由继续使用当前路由的情况下将控制权传递给后续路由。

路由处理器可以是函数、函数数组或两者的组合形式,如以下示例所示。

// 一个回调函数可以处理一个路由。例如:
app.get('/example/a', function (req, res) {
  res.send('Hello from A!')
})
// 多个回调函数可以处理一个路由(确保指定next对象作为参数)。例如:
app.get('/example/b', function (req, res, next) {
  console.log('the response will be sent by the next function ...')
  next()
}, function (req, res) {
  res.send('Hello from B!')
})
// 一个回调函数数组可以处理一个路由。例如:
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])
// 单独的函数和函数数组的组合可以处理一个路由。例如:
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!')
})

响应方法(Response methods)

下表中响应对象(res)的方法可以向客户端发送响应,并终止请求响应周期。如果路由处理器中没有调用以下任何方法,则客户端请求将一直挂起。

方法描述
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()为路由路径创建可链接的路由处理器。因为路径是在单个位置指定的,所以创建模块化路由很有帮助,减少了冗余和打字错误。有关路由的详细信息,请参阅:router()文档

下面是一个使用app.route()定义的链接路由处理器示例。

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的路由文件,内容如下:

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

// middleware that is specific to this 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

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

var birds = require('./birds')
// ...
app.use('/birds', birds)

应用程序现在可以处理对/birds/birds/about的请求,也可以调用特定于这个路由的timeLog中间件函数。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值