You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.26 03:15:03