NodeJS Express触发decodeURIComponent错误时如何记录请求来源IP地址
解决方案
你遇到的报错是Express路由层解析请求路径参数时,因路径包含非法编码字符触发decodeURIComponent抛出的同步错误,默认未配置错误处理中间件的情况下会直接输出到控制台,不会进入业务路由逻辑。可通过以下步骤获取请求IP并拦截:
1. 添加全局错误处理中间件(最简方案)
在所有路由、其他中间件的最后位置添加4参数的Express专属错误处理中间件,即可捕获该类错误并拿到请求对象:
// 错误处理中间件必须保留4个入参,顺序不可修改 app.use((err, req, res, next) => { // 匹配参数解码异常的错误 if (err instanceof URIError && err.message.includes('Failed to decode param')) { // 记录请求IP、路径、UA等关键信息 console.error(`异常解码请求:IP=${req.ip},路径=${req.originalUrl},UA=${req.get('User-Agent')},时间=${new Date().toISOString()}`) // 此处可添加自定义拉黑逻辑,例如将IP写入黑名单集合,后续请求直接拦截 return res.status(400).send('Bad Request') } // 其他错误走原有处理逻辑 next(err) })
2. 配置真实IP获取
如果服务前部署了Nginx、CDN等反向代理,需要在所有中间件的最前面开启代理信任配置,才能拿到客户端真实IP而非代理IP:
// 数值为代理层数,单层反向代理填1,多层按需调整,也可传入信任的代理IP段 app.set('trust proxy', 1)
3. 可选前置拦截方案
如果想在路由解析前就拦截所有非法编码的探测请求,可在所有中间件最前面加预校验中间件,更早完成拦截:
app.use((req, res, next) => { try { // 提前尝试解码完整请求路径 decodeURIComponent(req.originalUrl) next() } catch (err) { if (err instanceof URIError) { console.error(`预拦截异常编码请求:IP=${req.ip},路径=${req.originalUrl}`) // 拉黑逻辑可在此处实现 return res.status(400).end() } next(err) } })
内容的提问来源于stack exchange,提问作者ginjaemocoes
相关产品推荐
相关产品推荐

