在每个路由调用上执行中间件



在我的Express应用程序中,我在routes.ts:中实现路由

var Router = express.Router();
Router.route('/models/:modelId')
.get(function (req, res) {
service.setParameter(req)
service.get(req,res)
});

Router.route('/models/:modelId')
.post(function (req, res) {
service.setParameter(req)
service.post(req,res)
});

和express.ts:

export const App = express()
App.use(express.json())
App.use(express.urlencoded({ extended: true }))
App.use(helmet())
App.use('/', Router)

在每次路由器调用时,我都想执行一段代码service.setParameter(req(,它从"params"中获取特定的参数,但我不想显式地添加到每个路由器方法中。

我尝试在路由器前后将其添加为中间件

App.use('/', Router)
App.use(function(req, res, next){
service.setParameter(req)
next()
})

但如果我在Router之前定义它,那么路由还没有设置,并且我没有得到我想要的参数,如果我在之后定义它,则中间件不会执行。

如何以通用的方式执行service.setParameter(req(,使其适用于所有路由?

express.ts文件中,您可以添加一个中间件,在挂载路由器之前执行此操作,然后直接使用next()。你可以这样做:

App.use('/*', (req, res, next) => {
service.setParameter(req);
next();
});
App.use('/', Router)

您需要将自定义中间件放置在app.use(..):内的上下文路径和路由器之间

const router = express.Router();
router.post('/', (req, res) => {
service.post(req,res);
});
router.get('/', (req, res) => {
service.get(req,res)
});
app.use('/models', (req, res, next) => {
service.setParameter(req);
next();
}, router);

有了上面的代码,中间件将被排除在对'/models'的所有请求之外。

您可以使用app.use(async (req,res,next) => {...})来声明在所有请求中执行的中间件,如果您希望首先调用该中间件,则必须在您的路由之前声明,中间件必须调用next()才能继续执行流,如果您想在请求结束时被调用,您必须将其放在声明的末尾,但放在错误中间件之前,在这种方法中,每个路由都必须在函数末尾调用next()

第一种方法

const express = require('express');
const app = express();
const router = express.Router();
router.post('/', async (req, res) => {
await service.post(req,res);
});
router.get('/', async (req, res) => {
await service.get(req,res)
});
app.use((req,res,next) => {
console.log("always called");
next();
});
app.use('/',router);

第二种方法

const express = require('express');
const app = express();
const router = express.Router();
router.post('/', async (req, res, next) => {
await service.post(req,res);
next();
});
router.get('/', async (req, res, next) => {
await service.get(req,res);
next();
});
app.use('/',router);
app.use((req,res) => {
console.log("always called");
});

感谢您的回答,他们帮助我更好地了解了Express上的路由工作原理。

我找到了另一个解决方案,我认为在我的情况下效果最好——使用Router.all((方法:

const setRequest = function(req, res, next){
logger.setRequest(request)
next()
}
Router.route('/models/:model_id')
.all(setRequest)
.get(function (req, res) {service.execute()})
.put(function (req, res) {service.execute()})

最新更新