Express.js封装为导出模块的中间件如何正确获取请求头header
问题根因
这个报错和「如何获取请求头」没有关系,本质是你导出/调用中间件的方式错误,导致Express没有正确把req/res/next三个参数传入中间件函数,才出现了req为undefined的问题。
正确的封装导出步骤
1. 独立模块的正确写法
你的中间件校验逻辑本身没有问题,只需要在独立文件(比如命名为authMiddleware.js)末尾添加导出语句即可,另外顺便补充了原有代码的两个小优化点:
const loger = require("easy-loger"); require('dotenv').config(); function authMiddleware(req, res, next){ const appApiKey = process.env.API_KEY; let requestApiKey = req.headers.apikey; // 优化:补充空值判断,原有只判断字符串"undefined"的逻辑有遗漏 if(requestApiKey === "undefined" || !requestApiKey){ loger.createLog('Try to authorize without api key from : '+ req.headers.host, 'info'); res.status(401); // 优化:添加return避免返回响应后继续执行后续代码 return res.json({ code: 403, message: 'You need to authorize in this route' }); } if(appApiKey === requestApiKey){ next(); }else { loger.createLog('Try to authorize user without rights with api key: '+ requestApiKey, 'info'); res.status(403); return res.json({ code: 403, message: 'You have not permission for this route' }); } } // 导出函数本身,不要加括号执行 module.exports = authMiddleware;
2. 路由文件的正确调用方式
在路由文件引入中间件后,直接把函数作为参数传入路由配置即可,千万不要加括号执行函数,这是最容易触发报错的原因:
const express = require('express'); const router = express.Router(); // 引入封装好的中间件 const authMiddleware = require('./authMiddleware'); // 正确写法:直接传入函数名,不要写成authMiddleware() router.get('/protected-route', authMiddleware, (req, res) => { res.json({code: 200, msg: '验证通过'}) })
错误原因说明
如果调用时加了括号写成authMiddleware(),等于在路由初始化时就提前执行了中间件函数,此时根本没有请求对象传入,自然就会触发Cannot read property 'headers' of undefined的报错。
内容的提问来源于stack exchange,提问作者dkrakowski
相关产品推荐
相关产品推荐

