Доступ к промежуточному программному обеспечению для req.params
Я хотел бы выделить фрагмент кода, который будет проверять либо req.params
, либо req.body
для значения, которое требуется для каждого запроса. Я нахожу, что если я попытаюсь получить доступ к этим значениям до app.use(app.router)
, тогда запрос не будет проанализирован для включения этих объектов. Если я попытаюсь вставить промежуточное ПО после app.use(app.router)
, тогда он будет пропущен вместе.
Что я могу сделать, чтобы работать с этими значениями в одном месте, чтобы работа была готова к использованию маршрутами и моделями, расположенными ниже по течению?
Ответы
Ответ 1
Вы не можете делать то, что вы пытаетесь сделать. https://github.com/strongloop/express/issues/2088 объясняет это очень четко.
Я пытаюсь сделать то, что вы пытаетесь сделать в течение некоторого времени, без успеха. Я, наконец, проследил эту проблему в github.
Ответ 2
Просто запустите промежуточное программное обеспечение с каждым маршрутом,
const middleware = (req, res, next) => {
console.log(req.params.id);
next();
};
app.get('/test/:id', middleware, (req, res) => {
res.send('hi');
});
Ответ 3
Поскольку мой первоначальный ответ не будет получать параметры маршрута из URL-адреса, например. /things/:foo
(хотя он получит параметры querystring и req.body), он не будет работать так, как мы хотим. Но другой вариант - написать функцию-оболочку, которая сделает все, что вам нужно, и применить ее к промежуточному программному обеспечению маршрута:
function checkForParam (fn) {
return function(req, res, next) {
if (req.param('foo') != 'bar') {
return res.send(403, 'No way Jose!');
}
fn (req, res, next);
};
}
Затем добавьте маршруты с помощью:
app.get('/things/:foo', checkForParam(function(req, res, next) {
// your middleware code here
});
Это запустит проверку и перейдет к вашему настраиваемому промежуточному программному обеспечению маршрута только в том случае, если оно пройдет.
Ответ 4
Мне нравится этот способ:
const controller = function (name, method) {
return function (req, res) {
// COERCE ID
if (req.method === 'GET' || req.method === 'DELETE') {
var _id = req.params && req.params._id || false
if (/^[0-9a-f]{24}$/.test(_id)) {
req.params._id = new ObjectID(_id)
}
else if (_id) {
return res.status(404).send('Page not found.')
}
}
require('./api/' + name + '.js')[method](req, res)
}
}
Затем:
app.get('/api/post/:_id', controller('posts', 'get'))
Ответ 5
Остается один вопрос: используете Express v. 3 или 4
Это очень важно здесь, потому что понятие в версии 4 отличается (также лучше).
например.
https://github.com/visionmedia/express/wiki/Migrating-from-3.x-to-4.x
app.use(app.router);//< --- эта строка будет удалена
Ответ 6
Вместо того, чтобы пытаться сделать это с помощью специального промежуточного программного обеспечения, вы можете просто добавить шаблон подстановки, который всегда будет выполняться перед вашими другими маршрутами, и проверить там параметр:
app.get('/*', function(req, res, next) {
if (req.param('foo')) {
// Do something
return next(); // or return res.send(403, 'no way!'), or whatever.
}
return next();
});