路由
路由是指应用顺序的端点(URI)怎样相应客户端要求,有关路由的引见,请参阅路由基础。
运用与HTTP要领相对应的Express app
对象的要领定义路由,比方,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')
})
路由要领
路由要领是从个中一个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要求要领加载中间件函数,比方,无论是运用GET、POST、PUT、DELETE照样http模块支撑的任何其他HTTP要求要领,都邑对路由“/secret”
的要求实行以下处置惩罚顺序。
app.all('/secret', function (req, res, next) {
console.log('Accessing the secret section ...')
next() // pass control to the next handler
})
路由途径
路由途径与要求要领连系,定义可以发出要求的端点,路由途径可以是字符串、字符串情势或正则表达式。
字符?
、+
、*
和()
是它们的正则表达式对应物的子集,连字符(-
)和点(.
)由字符串途径按字面诠释。
假如你需要在途径字符串中运用美圆字符($
),请将其包括在([
和])
中,比方,“/data/$book”
处的要求的途径字符串将是“/data/([\$])book”
。
Express运用
path-to-regexp来婚配路由途径,有关定义路由途径的一切可能性,请参阅
path-to-regexp
文档,
Express Route Tester是一个用于测试基础Express路由的便利东西,但它不支撑情势婚配。查询字符串不是路由途径的一部分。
以下是基于字符串的路由途径的一些示例。
此路由途径将婚配对根路由/
的要求。
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')
})
以下是基于字符串情势的路由途径的一些示例。
此路由途径将婚配acd
和abcd
。
app.get('/ab?cd', function (req, res) {
res.send('ab?cd')
})
此路由途径将婚配abcd
、abbcd
、abbbcd
等。
app.get('/ab+cd', function (req, res) {
res.send('ab+cd')
})
此路由途径将婚配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')
})
基于正则表达式的路由途径示例:
此路由途径将婚配个中包括“a
”的任何内容。
app.get(/a/, function (req, res) {
res.send('/a/')
})
这个路由途径将与butterfly
和dragonfly
相婚配,但不会与butterflyman
、dragonflyman
等相婚配。
app.get(/.*fly$/, function (req, res) {
res.send('/.*fly$/')
})
路由参数
路由参数是定名的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中修复。
路由处置惩罚顺序
你可以供应多个回调函数,其行动类似于中间件来处置惩罚要求,唯一的破例是这些回调可能会挪用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!')
})
相应要领
下表中的相应对象(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
实例是一个完全的中间件和路由体系,因而,它一般被称为“迷你应用顺序”。
以下示例将路由器建立为模块,在个中加载中间件功用,定义一些路由,并将路由器模块装载在主应用顺序中的途径上。
在应用顺序目次中建立名为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
中间件函数。