2016-07-15 59 views
1
const app = express(); 
var router = require('express').Router({mergeParams: true}); 
const payloadMiddleware = (req, resp, next) => { 
    console.log('A:',req.params); 
    const {params, query} = req; 
    const payload = req.body; 
    req.my_params = { params, query, payload }; 
    next(); 
}; 

router.use(payloadMiddleware); 

router.get('/inventory/:itemID/price', async function GetPrice(req, res, next) { 
    console.log('B', req.my_params); 
    console.log('C', req.params); 
} 

app.use(bodyParser.urlencoded({extended: true})); 
app.use(bodyParser.json()); 
app.use('/', router); 
server = app.listen(port); 

GET /inventory/abc/price?a=1&b=2產生空PARAMS在express.js中間件對象

A: {} # unclear why this is empty 
B: { params: {}, 
    query: { a: '1', b: '2' }, 
    payload: {} } 
C: {itemID: 'abc'} 

所以我很困惑:我希望我的中間件找到paramsreq,構建新的對象,它分配給reqmy_params,然後將其傳遞給庫存處理程序。這部分發生,查詢字符串正在被解析,然後被分配到我的中間件中。爲什麼req.params === {}在我的中間件功能中,但是req.params = {itemID: 'abc'}在GET處理程序本身中?

沒有其它的路由具有相同的圖案,沒有其他中間件...

當我刪除選項也沒有觀察到變化從所述第二線對象,即var router = require('express').Router();

回答

4

payloadMiddleware是一個通用中間件未聲明爲包含參數的任何特定的URL模式(它匹配任何請求)。

Express也不知道傳遞給中間件的請求最終會在/inventory/:itemID/price的處理程序中結束。

如果你想在中間件接收參數,你必須明確使用它對抗模式匹配的路線:

app.use('/inventory/:itemID/price', payloadMiddleware); 

或者作爲路由處理的部分:

router.get('/inventory/:itemID/price', payloadMiddleware, async function ...); 
+0

我根據我對express文檔默認掛載點的理解,基於此:「使用指定的中間件功能或可選的掛載路徑路徑,默認爲」/「。」那麼只有中間件在給定路徑上專用'use'd纔會設置params?沒有辦法指定我希望使用該中間件併爲每個請求提供路徑參數? – Ben

+0

@不,這是不可能的,主要是因爲一箇中間件單獨使用時,會忽略其他中間件或路由處理程序。如果一個請求最終會匹配一個特定的參數化路由模式,Express甚至不會事先知道,所以它不能預先生成'req.params'(也是因爲你可能有很多參數化路由,所以不知道在哪裏一個請求會結束,它不會知道解析哪些路由參數)。 – robertklep