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

React项目中如何处理react-router-dom场景下非法URL触发的URIError?

非法URL百分号编码导致React Router崩溃的解决方案

这个问题的核心是react-router-dom内部解析路径时调用的decodeURI()/decodeURIComponent()方法,遇到不符合规范的百分号编码(比如单独的%、%2这类不完整编码)时会直接抛出URIError,没有做内置的异常捕获,导致错误向上溢出触发页面崩溃。以下是3种可行的兜底方案:

  • 方案1:全局异常兜底捕获
    在项目入口文件(如index.js/main.tsx)最顶部添加全局未捕获错误监听,直接拦截URI异常并做跳转处理:
window.addEventListener('error', (e) => {
  // 识别URI编码异常
  if (e.name === 'URIError' || e.message.includes('URI malformed')) {
    e.preventDefault()
    // 直接跳转404页面,也可以根据业务逻辑做其他处理
    window.location.replace('/404')
  }
})
  • 方案2:预校验URL编码合法性
    在路由初始化之前先对当前URL路径做安全解码校验,提前识别非法编码:
// 封装安全解码方法,解码失败不会抛错
const safeDecodeURI = (path) => {
  try {
    return decodeURI(path)
  } catch (err) {
    return null
  }
}

// 路由初始化前先校验
if (safeDecodeURI(window.location.pathname) === null) {
  window.location.replace('/404')
}
  • 方案3:外层包裹ErrorBoundary做组件级捕获
    如果错误是在React组件渲染阶段抛出,可以通过ErrorBoundary捕获后直接渲染404页面,避免用户看到堆栈或白屏:
import React from 'react'
import { BrowserRouter } from 'react-router-dom'
import NotFoundPage from './pages/404'

class URICatchErrorBoundary extends React.Component {
  constructor(props) {
    super(props)
    this.state = {
      hasURLError: false
    }
  }

  static getDerivedStateFromError(error) {
    if (error.name === 'URIError') {
      return { hasURLError: true }
    }
    return {}
  }

  render() {
    if (this.state.hasURLError) {
      return <NotFoundPage />
    }
    return this.props.children
  }
}

// 根组件渲染时包裹Router
root.render(
  <URICatchErrorBoundary>
    <BrowserRouter>
      <App />
    </BrowserRouter>
  </URICatchErrorBoundary>
)

生产环境建议同时使用全局监听+ErrorBoundary的双重兜底方案,覆盖所有可能的异常抛出场景。

内容的提问来源于stack exchange,提问作者FerJoTello

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 00:57:03