Маршрутизация
Маршрутизация описывает, как конечные точки приложения (URI) отвечают на запросы клиента. Для знакомства с маршрутизацией см. Основные маршруты.
Вы определяете маршрутизацию, используя методы объекта Express app , которые соответствуют HTTP-методам; например, app.get() для обработки GET-запросов и app.post для обработки POST-запросов. Полный список см. в app.METHOD. Также можно использовать app.all() для обработки всех HTTP-методов и app.use() для указания middleware в качестве функции обратного вызова (подробности см. в Использование middleware).
Эти методы маршрутизации задают функцию обратного вызова (иногда называемую «функцией обработчика»), которая вызывается при получении приложением запроса на указанный маршрут (конечную точку) и HTTP-метод. Другими словами, приложение «слушает» запросы, соответствующие указанным маршруту(ам) и методу(ам), и при обнаружении совпадения вызывает указанную функцию обратного вызова.
На самом деле, методы маршрутизации могут иметь более одной функции обратного вызова в качестве аргументов. При использовании нескольких функций обратного вызова важно предоставить next в качестве аргумента функции обратного вызова и затем вызвать next() внутри тела функции, чтобы передать управление следующей функции обратного вызова.
Следующий код является примером очень простого маршрута.
const express = require('express')
const app = express()
// respond with "hello world" when a GET request is made to the homepage
app.get('/', (req, res) => {
res.send('hello world')
})
Методы маршрутов
Метод маршрута происходит от одного из HTTP-методов и прикреплен к экземпляру класса express.
Следующий код является примером маршрутов, которые определены для методов GET и POST для корня приложения.
// GET method route
app.get('/', (req, res) => {
res.send('GET request to the homepage')
})
// POST method route
app.post('/', (req, res) => {
res.send('POST request to the homepage')
})
Express поддерживает методы, соответствующие всем HTTP-методам запроса: get, post, и так далее. Полный список см. в app.METHOD.
Существует специальный метод маршрутизации app.all(), используемый для загрузки функций middleware по пути для всех HTTP-методов запроса. Например, следующий обработчик выполняется для запросов на маршрут "/secret" независимо от того, используется ли GET, POST, PUT, DELETE, или любой другой HTTP-метод запроса, поддерживаемый в модуле http.
app.all('/secret', (req, res, next) => {
console.log('Accessing the secret section ...')
next() // pass control to the next handler
})
Пути маршрутов
Пути маршрутов в сочетании с методом запроса определяют конечные точки, с которых можно отправлять запросы. Пути маршрутов могут быть строками, шаблонами строк или регулярными выражениями.
Внимание
В express 5 символы ?, +, *, [], и () обрабатываются иначе, чем в версии 4, пожалуйста, ознакомьтесь с руководством по миграции для получения дополнительной информации.
Внимание
В express 4 символы регулярных выражений, такие как $ , должны быть экранированы с помощью \.
Примечание
Express использует path-to-regexp для сопоставления путей маршрутов; см. документацию path-to-regexp для всех возможностей определения путей маршрутов. Express Playground Router — полезный инструмент для тестирования основных маршрутов Express, хотя он не поддерживает сопоставление шаблонов.
Предупреждение
Строки запроса не являются частью пути маршрута.
Пути маршрутов на основе строк
Этот путь маршрута будет соответствовать запросам на корневой маршрут, /.
app.get('/', (req, res) => {
res.send('root')
})
Этот путь маршрута будет соответствовать запросам на /about.
app.get('/about', (req, res) => {
res.send('about')
})
Этот путь маршрута будет соответствовать запросам на /random.text.
app.get('/random.text', (req, res) => {
res.send('random.text')
})
Пути маршрутов на основе шаблонов строк
Внимание
Шаблоны строк в Express 5 больше не работают. Пожалуйста, обратитесь к руководству по миграции для получения дополнительной информации.
Этот путь маршрута будет соответствовать acd и abcd.
app.get('/ab?cd', (req, res) => {
res.send('ab?cd')
})
Этот путь маршрута будет соответствовать abcd, abbcd, abbbcd, и так далее.
app.get('/ab+cd', (req, res) => {
res.send('ab+cd')
})
Этот путь маршрута будет соответствовать abcd, abxcd, abRANDOMcd, ab123cd, и так далее.
app.get('/ab*cd', (req, res) => {
res.send('ab*cd')
})
Этот путь маршрута будет соответствовать /abe и /abcde.
app.get('/ab(cd)?e', (req, res) => {
res.send('ab(cd)?e')
})
Пути маршрутов на основе регулярных выражений
Этот путь маршрута будет соответствовать любому пути, содержащему букву «а».
app.get(/a/, (req, res) => {
res.send('/a/')
})
Этот путь маршрута будет соответствовать butterfly и dragonfly, но не butterflyman, dragonflyman, и так далее.
app.get(/.*fly$/, (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', (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" }
Внимание
В express 5 символы Regexp не поддерживаются в путях маршрутов, для получения дополнительной информации обратитесь к руководству по миграции.
Чтобы получить больший контроль над точной строкой, которая может быть сопоставлена параметром маршрута, можно добавить регулярное выражение в скобки (()):
Route path: /user/:userId(\d+)
Request URL: http://localhost:3000/user/42
req.params: {"userId": "42"}
Предупреждение
Поскольку регулярное выражение обычно является частью литеральной строки, убедитесь, что вы экранируете все символы \ с помощью дополнительной обратной косой черты, например, \\d+.
Предупреждение
В Express 4.x символ * в регулярных выражениях не интерпретируется обычным способом. В качестве обходного решения используйте {0,} вместо *. Вероятно, это будет исправлено в Express 5.
Обработчики маршрутов
Вы можете предоставить несколько функций обратного вызова, которые ведут себя как middleware для обработки запроса. Единственное исключение состоит в том, что эти вызовы могут вызвать next('route') для обхода оставшихся маршрутных вызовов. Вы можете использовать этот механизм, чтобы наложить предварительные условия на маршрут, а затем передать управление последующим маршрутам, если нет причин продолжать по текущему маршруту.
Обработчики маршрутов могут быть функциями, массивами функций или комбинацией обоих, как показано в следующих примерах.
Одинарная функция обратного вызова может обрабатывать маршрут. Например:
app.get('/example/a', (req, res) => {
res.send('Hello from A!')
})
Более одной функции обратного вызова может обрабатывать маршрут (убедитесь, что вы указали объект next). Например:
app.get('/example/b', (req, res, next) => {
console.log('the response will be sent by the next function ...')
next()
}, (req, res) => {
res.send('Hello from B!')
})
Массив функций обратного вызова может обрабатывать маршрут. Например:
const cb0 = function (req, res, next) {
console.log('CB0')
next()
}
const cb1 = function (req, res, next) {
console.log('CB1')
next()
}
const cb2 = function (req, res) {
res.send('Hello from C!')
}
app.get('/example/c', [cb0, cb1, cb2])
Комбинация независимых функций и массивов функций может обрабатывать маршрут. Например:
const cb0 = function (req, res, next) {
console.log('CB0')
next()
}
const cb1 = function (req, res, next) {
console.log('CB1')
next()
}
app.get('/example/d', [cb0, cb1], (req, res, next) => {
console.log('the response will be sent by the next function ...')
next()
}, (req, res) => {
res.send('Hello from D!')
})
Методы ответа
Методы объекта ответа (res ) в следующей таблице могут отправлять ответ клиенту и завершать цикл запроса-ответа. Если ни один из этих методов не будет вызван из обработчика маршрута, запрос клиента останется висящим.
| Метод | Описание |
|---|---|
| res.download() | Запрашивает загрузку файла. |
| res.end() | Завершает процесс ответа. |
| res.json() | Отправка ответа в формате JSON. |
| res.jsonp() | Отправка ответа в формате JSON с поддержкой JSONP. |
| res.redirect() | Перенаправление запроса. |
| res.render() | Вывод шаблона представления. |
| res.send() | Отправка ответа различных типов. |
| res.sendFile() | Отправка файла как потока octet-stream. |
| res.sendStatus() | Устанавливает код состояния ответа и отправляет его строковое представление в качестве тела ответа. |
app.route()
Вы можете создать цепные обработчики маршрутов для пути маршрута, используя app.route(). Поскольку путь указан в одном месте, создание модульных маршрутов полезно, как и сокращение избыточности и ошибок ввода. Дополнительную информацию о маршрутах см.: Документация Router().
Вот пример цепных обработчиков маршрутов, которые определены с помощью app.route().
app.route('/book')
.get((req, res) => {
res.send('Get a random book')
})
.post((req, res) => {
res.send('Add a book')
})
.put((req, res) => {
res.send('Update the book')
})
express.Router
Используйте класс express.Router для создания модульных, монтируемых обработчиков маршрутов. Экземпляр Router представляет собой полную систему middleware и маршрутизации; по этой причине его часто называют «мини-приложением».
Следующий пример создает роутер в виде модуля, загружает в него функцию middleware, определяет некоторые маршруты и монтирует модуль роутера на путь в главном приложении.
Создайте файл роутера с именем birds.js в каталоге приложения со следующим содержимым:
const express = require('express')
const router = express.Router()
// middleware that is specific to this router
const timeLog = (req, res, next) => {
console.log('Time: ', Date.now())
next()
}
router.use(timeLog)
// define the home page route
router.get('/', (req, res) => {
res.send('Birds home page')
})
// define the about route
router.get('/about', (req, res) => {
res.send('About birds')
})
module.exports = router
Затем загрузите модуль роутера в приложение:
const birds = require('./birds')
// ...
app.use('/birds', birds)
Теперь приложение сможет обрабатывать запросы к /birds и /birds/about, а также вызывать функцию middleware timeLog, которая специфична для маршрута.
Но если у родительского маршрута /birds есть параметры пути, он по умолчанию не будет доступен из дочерних маршрутов. Чтобы сделать его доступным, вам нужно передать параметр mergeParams в конструктор Router справка.
const router = express.Router({ mergeParams: true })
© 2017 StrongLoop, IBM, and other expressjs.com contributors.
Licensed under the Creative Commons Attribution-ShareAlike License v3.0.
https://expressjs.com/en/guide/routing.html