Express API
Express
- самый популярный на сегодняшний деньNode.js-фреймворк
для разработки веб-серверов.
Официальное руководство по Express
на русском языке.
express
Создает приложение Express
.
const express = require('express')
const app = express()
Методы
express.json(options?)
Встроенный посредник, разбирающий входящие запросы в объект в формате JSON. основан на body-parser
. Разобранные данные попадают в тело запроса (req.body
). Если данных в запросе не было, Content-Type
отличается от application/json
или возникла ошибка, то возвращается пустой объект ({}
).
app.use(express.json())
Обратите внимание: форма req.body
определяется пользователем, поэтому все свойства и значения этого объекта являются ненадежными (untrusted) и должны проходить валидацию перед использованием.
Настройки (options)
inflate: true
- обработка сжатых данныхlimit: '100kb'
- максимальный размер тела запроса в виде числа (байты) или строки (разбирается с помощью библиотекиbytes
)reviver: null
- второй аргумент, передаваемый вJSON.parse()
strict: true
- обработка только массивов и объектовtype: 'application/json'
- определение медиа-типа, разбираемого посредником в виде строки, массива строк или функцииverify: undefined
-verify(req, res, buf, encoding)
, гдеbuf
- этоBuffer
необработанного (raw) тела запроса, аencoding
- кодировка запроса
express.static(root, options?)
Встроенный посредник для обслуживания (serve) статических файлов. Основан на библиотеке serve-static
.
root
- корневая директория со статическими файлами. Файлы для обслуживанию определяются посредством комбинации req.url
с root
. Если запрашиваемый файл отсутствует, то вместо ответа 404, вызывается next()
для передачи управления следующему посреднику, который может предоставлять резервный контент.
Настройки
dotfiles: 'ignore'
- обработка файлов, начинающихся с точки, например,.env
etag: true
- генерацияetag
extensions: false
- расширения резервных файлов, например,['html', 'htm']
fallthrough: true
- позволяет клиентским ошибкам проваливаться в качестве необработанных запросовimmutable: false
- управление директивойimmutable
в заголовке ответаCache-Control
. Если включено, для управления кэшированием также должна быть определена настройкаmaxAge
. Директиваimmutable
запрещает клиентам делать условные запросы для определения изменений файла в течениеmaxAge
index: 'index.html'
- индексируемый (главный) файл директорииlastModified: true
- устанавливает заголовокLast-Modified
со временем последнего измененияmaxAge: 0
- время жизни (максимальный возраст) кэша в мс или в виде строкиredirect: true
- перенаправление к завершающему/
в случае, когда название пути - это директорияsetHeaders
- функция для установки заголовков для обслуживаемого файла. Сигнатура:fn(res, path, stat)
, гдеres
- объект ответа,path
- адрес файла для отправки,stat
- объект со статистикой файла для отправки
Пример
Из документации:
const options = {
dotfiles: 'ignore',
etag: false,
extensions: ['htm', 'html'],
index: false,
maxAge: '1d',
redirect: false,
setHeaders: function (res, path, stat) {
res.set('x-timestamp', Date.now())
}
}
app.use(express.static('public', options))
Обычно, нам не нужны настройки, но необходимо правильно определить путь к root
:
app.use(express.static(path.join(__dirname, 'public'))) // path.resolve()
express.Router(options?)
Создает новый объект роутера.
const router = express.Router()
// или
const router = require('express').Router()
Настройки
caseSensitive: false
- чувствительность к регистру (/Foo
и/foo
- одинаковые маршруты)mergeParams: false
- если дочерние и родительские параметры совпадают, дочерние имеют приоритетstrict: false
- строгая маршрутизация (/foo
и/foo/
- одинаковые маршруты)
express.urlencoded(options?)
Встроенный посредник, разбирающий полезную нагрузку строки запроса (например, в application/x-www-form-urlencoded
значения кодируются в кортежах с ключом, разделенных символом &
, с =
между ключом и значением: ?foo=bar&baz=qux
). Основан на body-parser
. В целом, поведение аналогично express.json()
.
Настройки
extended: true
- библиотека для разбора строки запроса:qs
-true
,querystring
-false
. Грубо говоря,extended: true
означает, чтоreq.body
может содержать любые значения,extended: false
- только строкиinflate: true
- см.express.json()
limit: '100kb'
- см.express.json()
parameterLimit: 1000
- максимальное количество параметровtype: application/x-www-form-urlencoded
- см.express.json()
verify: undefined
- см.express.json()
Application (приложение)
Приложение Express
.
const express = require('express')
const app = express()
app.get('/', (req, res) => {
res.send('Привет, народ!')
})
Объект app
содержит методы для
- роутинга HTTP-запросов, например,
app.METHOD
иapp.param
- настройки посредников,
app.route()
- рендеринга представлений (views) HTML,
app.render()
- регистрации шаблонизаторов,
app.engine()
Свойства
app.locals
Объект, свойства которого являются локальными переменными приложения:
console.log(app.locals.title) // My App
console.log(app.locals.email) // my@email.com
После установки, значения свойств app.locals
будут существовать на протяжении всего жизненного цикла приложения, в отличие от res.locals
, которые являются валидными только на протяжении жизненного цикла запроса.
Локальные переменные доступны в шаблонах, которые рендерятся в приложении. Они также доступны в посредниках через req.app.locals
.
app.locals.title = 'My App'
app.locals.email = 'my@email.com'
app.mountpath
Данное свойство содержит один или более паттернов путей монтирования субприложений (sub-apps - экземпляр express
, который может использоваться для обработки запроса к маршруту):
const express = require('express')
const app = express() // основное приложение
const admin = express() // дополнительное приложение
admin.get('/', (req, res) => {
console.log(admin.mountpath) // /admin
res.send('Admin Homepage')
})
app.use('/admin', admin) // монтирование дополнительного приложения
Это похоже на свойство baseUrl
объекта req
, за исключением того, что req.baseUrl
возвращает совпавший путь URL, а не совпавшие паттерны.
app.router
- встроенный экземпляр роутера. Создается автоматически при первом доступе
const express = require('express')
const app = express()
const { router } = app
router.get('/', (req, res) => {...})
app.listen(5000)
События
app.on('mount', callback(parent))
Событие, возникающее при монтировании дополнительного п риложения в родительское. Последнее передается в колбек.
Обратите внимание: дополнительные приложения не наследуют дефолтные настройки родительского приложения, но наследуют кастомные.
const admin = express()
admin.on('mount', (parent) => {
console.log('Admin Mounted')
console.log(parent) // ссылка на родительское приложение
})
admin.get('/', (req, res) => {...})
app.use('/admin', admin)
Методы
app.all(path, callback)
Данный метод похож на обычные методы app.METHOD()
, но совпадает для всех глаголов HTTP.
Аргументы
path: '/'
- путь для которого вызывается посредник в виде строки, паттерна, регулярного выражения, массиваcallback
- посредник, несколько посредников, разделенных запятыми, массив посредников, их комбинация
Следующий колбек выполняется для запросов к /secret
при использовании любого HTTP-метода (GET, POST, PUT, DELETE и т.д.):
app.all('/secret', (req, res, next) => {
console.log('Доступ к закрытому разделу...')
next() // передаем управление следующему обработчику
})
Проверка аутентификации и загрузка данных пользователя:
app.all('*', requireAuthentication, loadUser)
Пример выполнения колбека для запросов к путям, которые начинаются с /api
:
app.all('/api/*', requireAuthentication)
app.delete(path, callback)
Вызывает колбек при DELETE-запросах к path
. Аргументы идентичны аргументам app.all()
.
app.delete('/user/remove/:id', async (req, res) => {
try {
// извлекаем `id` из параметров запроса
const { id } = req.params
// используем Mongoose-модель `User` для поиска пользователя по `id`
const user = await User.findById(id)
// сравниваем пароли
// в реальном приложении пароль пользователя
// хешируется перед сохранением пользователя в базе данных
// соответственно, логика сравнения паролей будет сложнее
const match = user.password === req.body.password
// если пароли не совпадают
if (!match) return res.status(400).json({ error: 'Введен неверный пароль' })
// удаляем пользователя
await User.findByIdAndRemove(id)
res.sendStatus(200)
} catch (err) {
res.sendStatus(500)
}
})
app.disable(name) и app.enable(name)
app.disable(name)
устанавливает значение настройки приложения (name
) в значение false
. app.enable(name)
включает настройку.
app.disabled(name) и app.enabled(name)
app.disabled(name)
возвращает true
, если настройка отключена. app.enabled(name)
- если настройка включена.
app.engine(ext, callback)
Регистрирует колбек шаблонизатора как ext
. Используется для шаблонизаторов, которые не предоставляют .__express
из коробки. Пример привязки EJS
к файлам с расширением .html
:
app.engine('html', require('ejs').renderFile)
app.get(name)
Возвращает значение настройки приложения (name
). Не путайте со следующим методом.
app.get(path, callback)
Вызывает колбек при GET-запросах к path
. Аргументы идентичны аргументам app.all()
.
Пример использования фреймворка Passport.js
для аутентификации с помощью Google-аккаунта.
app.get('/google',
passport.authenticate('google', {
scope: ['profile']
}))
app.listen(path, callback?)
Запускает UNIX-сокет и регистрирует соединения по указанному адресу. Не путайте со следующим методом. Данный метод идентичен http.Server.listen()
из Node.js
.
app.listen(port, host?, backlog?, callback)
Привязывает приложение (binds) и регистрирует соединения по определенному порту и хосту. Данный метод также идентичен http.Server.listen()
.
Если порт не указан или его значением является 0
, операционная система использует произвольный порт.
const express = require('express')
const app = express()
app.listen(process.env.PORT || 5000)
Приложение, возвращаемое express()
- в действительности, всего лишь функция, спроектированная для передачи в качестве колбека для обработки запросов в Node.js-сервер. Это позволяет реализовать HTTP и HTTPS версии приложения с помощью одной кодовой базы:
const express = require('express')
const https = require('https')
const http = require('http')
const app = express()
http.createServer(app).listen(80)
https.createServer(options, app).listen(443)
Метод app.listen()
возвращает объект http.Server
, который (для HTTP) выглядит следующим образом:
app.listen = function () {
const server = http.createServer(this)
return server.listen.apply(server, arguments)
}
app.METHOD(path, callback)
Вызывает колбек при HTTP-запросах к path
c использованием указанного METHOD
. Аргументы идентичны аргументам app.all()
.
Методы маршрутизации
Express
поддерживает следующие методы HTTP-запросов:
checkout
copy
delete
get
head
lock
merge
mkactivity
mkcol
move
m-search
notify
options
patch
post
purge
put
report
search
subscribe
trace
unlock
unsubscribe
В документации описываются наиболее популярные методы (GET, POST, PUT и DELETE), но другие методы работают точно также.
Для методов, которые преобразуются в невалидные названия переменных, следует использовать скобочную нотацию, например, app['m-search']('/', (req, res) => {...})
.
app.param(name, callback)
Добавляем колбек, запускаемый для параметров маршрута, где name
- название параметра или массив таких названий. Параметрами колбека являются: объект запроса, объект ответа, посредник next()
, значение параметра и его название (именно в таком порядке).
Если name
- это массив, callback
регистрируется для каждого параметра в том порядке, в котором они определены. Более того, для каждого параметра, кроме последнего, вызов next()
запускает колбек для следюущего параметра. Вызов next()
в колбеке последнего параметра передает управление следующему посреднику.
Например, когда в адресе маршрута имеется :user
, можно реализовать логику загрузки данных пользователя для автоматического предоставления req.user
маршрутизатору или выполнить валидацию входящего параметра:
app.param('user', async (req, res, next, id) => {
try {
// пробуем получить данные пользователя и прикрепить их к объекту запроса
const user = await User.findById(id)
if (!user) return res.status(404).json({ error: 'Пользователь не найден' })
req.user = user
next()
} catch (err) {
next(err)
}
})
Колбек является локальным для роутера, на котором он определен.
Такие колбеки вызываются перед другими обработчиками, в которых появляется данный параметр, и они вызываются только один раз в цикле запрос-ответ, даже если параметр совпадает для нескольких маршрутизаторов:
app.param('id', (req, res, next, id) => {
console.log('Вызывается только один раз')
next()
})
app.get('/user/:id', (req, res, next) => {
console.log('Параметр совпадает с этим маршрутизатором')
next()
})
app.get('/user/:id', (req, res) => {
console.log('И с этим тоже')
res.end()
})
При запросе /user/42
, вывод в консоли будет следующим:
Вызывается только один раз
Параметр совпадает с этим маршрутизатором
И с этим тоже
app.param(['id', 'page'], (req, res, next, value) => {
console.log('Вызывается только о дин раз со значением ', value)
next()
})
app.get('/user/:id/:page', (req, res, next) => {
console.log('Есть совпадение')
next()
})
app.get('/user/:id/:page', (req, res) => {
console.log('И еще одно')
res.end()
})
При запросе /user/42/3
вывод в консоли будет таким:
Вызывается только один раз со значением 42
Вызывается только один раз со значением 3
Есть совпадение
И еще одно
app.path()
Возвращает канонический путь приложения. Обычно, для получения такого пути лучше использовать req.baseUrl()
.
app.post(path, callback)
Вызывает колбек при POST-запросах к path
. Аргументы идентичны аргументам app.all()
.
Пример сохранения данных пользователя в базе данных:
// в реальных приложениях записи данных пользователя в БД
// предшествует валидация этих данных,
// например, с помощью посредника `express-validator`
app.post('/user/register', registerValidators, async (req, res) => {
const { username, password } = req.body
// также перед тем, как сохранить пароль пользователя в БД,
// он подвергается хешированию, например, с помощью библиотеки `bcrypt`
const hashedPassword = await generatePassword(password)
try {
const newUser = new User({
username,
hashedPassword
})
const savedUser = await newUser.save()
// для проверки аутентификации пользователя
// используются токены, сгенерированные, например,
// с помощью библиотеки `jsonwebtoken` (один из возможных вариантов)
const token = generateToken(savedUser)
res.status(200).json({ user: savedUser, token })
} catch (err) {
res.sendStatus(500)
}
})
app.put(path, callback)
Вызывает колбек при PUT-запросах к path
. Аргументы идентичны аргументам app.all()
.
Пример обновления поста:
// проверка аутентификации с помощью `passport`
app.use(passport.authenticate('jwt', { session: false }))
app.put('/post/update/:id', async (req, res) => {
try {
await Post.findByIdAndUpdate(req.params.id, req.body)
res.sendStatus(200)
} catch (err) {
res.sendStatus(500)
}
})
app.render(view, locals?, callback)
Возвращает отрендеренные HTML представления через колбек. Принимает опциональный параметр - объект с локальными переменными для представления. Похож на res.render()
, но не может автоматически отправлять отрендеренные представления клиенту. res.render()
использует app.render()
для рендеринга представления.
app.route(path)
Возвращает экземпляр роутера, который можно использовать для обработки HTTP-запросов с опциональными посредниками. Позволяет избежать дублирования названий маршрутов и связанных с этим ошибок:
const app = express()
app.route('/events')
.all((req, res, next) => {
// запускается для всех запросов
})
.get((req, res, next) => {
res.json()
})
.post((res, req, next) => {...})
app.set(name, value)
Присваивает значение указанной настройке. Можно сохранять любые значения, кроме зарезервированных (см. ниже).
Вызов app.set('foo', true)
идентичен вызову app.enable('foo')
, а вызов app.set('foo', false)
- app.disable('foo')
.
Значение настройки можно получить с помощью app.get()
:
app.set('title', 'My Site')
app.get('title') // My Site
Настройки приложения
Обратите внимание, что дополнительные приложения не наследуют дефолтные настройки, но наследуют некоторые кастомные.
case sensitive routing: undefined
- чувствительная к регистру маршрутизацияenv: process.env.NODE_ENV | 'development' (process.env.NODE_ENV === undefined)
- режим окруженияetag: weak
- устанавливает заголовокEtag
jsonp callback name: 'callback'
- определяет дефолтное название колбека JSONPjson escape: undefined
- включает обезвреживание JSON-ответов изres.json
,res.jsonp
иres.send
. Наследуется субприложениямиjson replacer: undefined
- аргументreplacer
методаJSON.stringify()
. Наследуется субприложениямиjson spaces: undefined
- аргументspace
методаJSON.stringify()
. Наследуется субприложениямиquery parser: 'extended'
- отключает разбор строки запроса приfalse
,simple
-querystring
,extended
-qs
. Кастомный парсер получает полную строку запроса и должен вернуть объект с ключами строки и ее значениямиstrict routing: undefined
- строгая маршрутизация. Наследуется субприложениямиsubdomain offset: 2
- количество разделенных точкой частей хоста, удаляемых при доступе к поддоменуtrust proxy: false
- указывает, что приложение использует прокси сервер, а также что для определения соединения и IP адреса клиента следует использовать заголовкиX-Forwarded-*
. Обратите внимание: названные заголовки легко подделываются, обнаруженные IP являются ненадежными. Массив IP, используемых клиентом для соединения, хранится вreq.ips
. Данная настройка реализована с помощью пакетаproxy-addr
. Наследуется субприложениямиviews: process.cwd() + '/views'
- директория или массив для представлений приложенияview cache: true (production) | undefined
- кэширование компиляции шаблонов представленийview engine: undefined
- дефолтное расширение движка рендеринга. Наследуется субприложениямиx-powered-by: true
- включает заголовокX-Powered-By: Express
app.use(path?, callback, callback?)
Монтирует определенного посредника (или посредников) в указанный путь: посредник выполняется при совпадении запрошенного адреса с аргументом path
. Аргументы идентичны аргументам app.all()
.
Описание
Если маршрут совпадает с путем, то количество переходов не имеет значения. Например, app.use('/apple', ...)
будет совпадать с /apple
, /apple/images
, /apple/images/news
и т.д.
Поскольку путем по умолчанию является /
, посредник без пути будет выполняться для любого запроса:
app.use((req, res, next) => {
console.log(`Текущее время ${new Date().toLocaleTimeString()}`)
next()
})
Посредники выполняются последовательно, так что порядок их добавления (включения) в приложение очень важен:
// данный посредник не позволит запросу выйти за его пределы
app.use((req, res, next) => {
res.send('Ты со мной навсегда')
})
// запросы никогда не достигнут этого маршрута
app.get('/', (req, res) => {
res.send('I miss you')
})
Посредники для обработки ошибок
Посредники для обработки ошибок отличаются от обычных посредников тем, что принимают 4 аргумента вместо 3. Обратите внимание: даже если вам не нужен метод next()
, вы все равно должны его указать дл я соблюдения сигнатуры, в противном случае, посредник будет интерпретирован как обычный:
app.use((err, req, res, next) => {
console.error(err.stack)
res.status(500).send('Что-то сломалось')
})
Примеры путей
/* path - путь */
// совпадает с путями, начинающимися с `/abcd`
app.use('/abcd', ...)
/* path pattern - паттерн пути */
// совпадает с `/abcd` и `/abd`
app.use('/abc?d', ...)
// совпадает с путями, которые начинаются с `/abcd`, `/abbcd`, `/abbbbbcd` и т.д.
app.use('/ab+cd', ...)
// совпадает с путями, которые начинаются с `/abcd`, `/abxcd`, `/abFOOcd`, `/abbArcd` и т.д.
app.use('/ab*cd', ...)
// совпадает с путями, начинающимися с `/ad` и `/abcd`
app.use('/a(bc)?d', ...)
/* регулярное выражение */
// совпадает с путями, начинающимися с `/abc` и `/xyz`
app.use(/\/abc|\/xyz/, ...)
/* массив */
// совпадает с путями, которые начинаются с `/abcd`, `/xyza`, `/lmn` и `/pqr`
app.use(['/abcd', '/xyza', /\/lmn|\/pqr/], ...)
Примеры посредников
В приведенных ниже примерах используется app.use()
, но то же самое справедливо и в отношении app.METHOD()
и app.all()
.
/* единичный посредник */
app.use((req, res, next) => {
next()
})
// роутер - это валид ный посредник
const router = express.Router()
router.get('/', (req, res, next) => {
next()
})
app.use(router)
// приложение `Express` - это также валидный посредник
const sub = express()
sub.get('/', (req, res, next) => {
next()
})
app.use(sub)
/* несколько посредников */
const r1 = express.Router()
rq.get('/', (req, res, next) => {
next()
})
const r2 = express.Router()
r2.get('/', (req, res, next) => {
next()
})
app.use(r1, r2)
/* массив */
const r1 = express.Router()
rq.get('/', (req, res, next) => {
next()
})
const r2 = express.Router()
r2.get('/', (req, res, next) => {
next()
})
app.use([r1, r2])
/* комбинация */
function mw1 (req, res, next) { next() }
function mw2 (req, res, next) { next() }
const r1 = express.Router()
r1.get('/', function (req, res, next) { next() })
const r2 = express.Router()
r2.get('/', function (req, res, next) { next() })
const sub = express()
sub.get('/', function (req, res, next) { next() })
app.use(mw1, [mw2, r1, r2], sub)
Примеры использования посредника express.static()
:
// обслуживание статического контента из директории `public`
// GET /style.css и т.д.
app.use(express.static(path.join(__dirname, 'public')))
// запрос должен иметь префикс `/static`
app.use('/static', express.static(path.join(__dirname, 'public')))
// отключает логгирование для статического контента
app.use(express.static(path.join(__dirname, 'public')))
app.use(morgan())
// несколько директорий со статическими файлами (`static` имеет приоритет)
app.use(express.static(path.join(__dirname, 'public')))
app.use(express.static(path.join(__dirname, 'files')))
app.use(express.static(path.join(__dirname, 'uploads')))
Request (запрос)
Объект req
представляет собой HTTP запрос и содержит свойства для строки запроса (query string), параметров (parameters), тела (body), HTTP заголовков (HTTP headers) и т.д. Название req
- это всего лишь соглашение, данный объект, как и объект res
(response, ответ), могут называться как угодно, но лучше придерживаться соглашения.
app.get('/', (req, res) => {
res.send(`user ${req.params.id}`)
})
Свойства
req.app
Данное свойство содержит ссылку на экземпляр приложения, которое использует посредника. Например, если мы создаем модуль, который экспортирует посредника, и require()
его в главном файле, тогда посредник может получить доступ к приложению через req.app
:
// index.js
app.get('/viewdir', require('./middleware.js'))
// middleware.js
module.exports = (req, res) => {
res.send(`Директория с представлениями - ${req.app.get('views')}`)
}
req.baseUrl
Путь URL, на котором монтирован экземпляр роутера. Похож на app.mountpath
, за исключением того, что последний возвращает совпавший паттерн пути.
const greet = express()
greet.get('/jp', (req, res) => {
console.log(req.baseUrl) // greet
res.send('Konichiwa!')
})
app.use('/greet', greet) // загружаем роутер на `/greet`
req.body
Содержит пары ключ-значение данных, содержащихся в запросе. По умолчанию имеет значение undefined
и наполянется данными такими посредниками, как express.json
или multer
:
const express = require('express')
const multer = require('multer')
const app = express()
const upload = multer() // для разбора `multipart/form-data`
app.use(express.json()) // для разбора `application/json`
app.use(express.urlencoded({extended: true})) // для разбора application/x-www-form-urlencoded
app.post('/profile', upload.array(), (req, res, next) => {
console.log(req.body)
req.json(req.body)
})
req.cookies
При использовании посредника cookie-parser
данное свойство представляет собой объект, содержащий куки, полученные из запроса, или пустой объект, если запрос не содержит куки.
// Cookie: name=john
console.log(req.cookies.name) // john
Для получения доступа к подписанным куки используется req.signedCookies
.
req.fresh
Если ответ является "свежим" в клиентском кэше, возвращается true
, иначе, возращается false
- это означает, что кэш клиента устарел и должен быть отправлен полный ответ. При установке клиентом Cache-Control: no-cache
, данный модуль вернет false
для перезагрузки запроса и прозрачной обработки ответа.
req.host
Содержит хост, полученный из заголовка Host
. При использовании настройки trust proxy
значением данного свойства является значение заголовка X-Forwarded-Host
. Данный заголовок может устанавливаться клиентом или прокси. Если в запросе имеется несколько X-Forwarded-Host
, используется значение первог о заголовка.
req.hostname
Содержит название хоста из заголовка Host
или X-Forwarded-Host
.
req.ip
Содержит удаленный IP-адрес запроса. При использовании настройки trust proxy
, значением данного свойства является последняя входная точка в заголовке X-Forwarded-For
. Данный заголовок может устанавливаться клиентом или прокси.
req.ips
При использовании настройки trust proxy
, данное свойство содержит массив IP-адресов, определенных в заголовке X-Forwarded-For
. В противном случае, его значением является пустой массив.
req.method
Содержит строковое представление HTTP-метода запроса: GET, POST, PUT, DELETE и т.д.
req.originalUrl
Данное свойство похоже на req.url
, но возвращает исходный запрос, позволяя перезаписывать req.url
для целей внутренней маршрутизации. Например, монтирование приложения с помощью app.use()
перезапишет req.url
точкой монтирования.
req.originalUrl
доступен как в посредниках, так и в роутерах и представляет собой комбинацию req.baseUrl
и req.url
:
// GET 'http://www.example.com/admin/new?sort=desc'
app.use('/admin', (req, res, next) => {
console.log(req.originalUrl) // '/admin/new?sort=desc'
console.log(req.baseUrl) // '/admin'
console.log(req.path) // '/new'
next()
})
req.params
Данное свойство представляет собой объект, содержащий свойства, связанные с именованными параметрами маршрута. Например, если у нас имеется маршрут user/:name
, тогда значение свойства name
можно получить через req.params.name
. Дефолтным значением является {}
.
// GET /user/john
console.log(req.params.name) // john
При использовании регулярного выражения для определения маршрута, группы захвата (()
) помещаются в массив с доступом через req.params[n]
, где n
- итая группа захвата. Данное правило также применяется в отношении "диких карточек" (wild cards), таких как /file/*
:
// GET /file/scripts/lodash.min.js
console.log(req.params[0]) // scripts/lodash.min.js
Для изменения ключей в req.params
следует использовать обработчик app.param()
. Изменения прмиеняются только к параметрам, определенным в маршруте.
Обратите внимание: Express
автоматически декодирует значения в req.params
с помощью decodeURIComponent()
.
req.path
Содержит путь запрошенного URL:
// example.com/users?sort=desc
console.log(req.path) // /users
req.protocol
Содержит протокол URL: http
или https
(trust proxy
- значение заголовка X-Forwarded-Proto
).
req.query
Данный объект содержит свойства для каждого параметра строки запроса. Если парсер строки запроса отключен, значением рассматриваемого свойства является {}
.
Обратите внимание: значения req.query
являются ненадежными и должны проходить валидацию перед использованием.
// GET /search?q=john+smith
console.log(req.query.q) // john smith
// GET /shoes?order=desc&shoe[color]=blue&shoe[type]=converse
console.log(req.query.order) // desc
console.log(req.query.shoe.color) // blue
console.log(req.query.shoe.type) // converse
// GET /shoes?color[]=blue&color[]=black&color[]=red
console.log(req.query.color) // [blue, black, red]