本文目录导读:

处理“路由未找到”(通常指 HTTP 404 或前端路由不匹配)的异常,是保障用户体验和系统健壮性的关键环节,根据你使用的是后端框架还是前端框架,处理方式有所不同。
以下是针对不同场景的详细处理方案和最佳实践。
后端框架(传统 Web 应用或 API)
当用户请求的 URL 在后端没有对应的路由处理器时,后端应返回明确的错误信息,而不是抛出堆栈跟踪或返回空白页。
通用原则
- 不要暴露敏感信息:生产环境应隐藏技术细节(如框架版本、文件路径)。
- 返回正确的状态码:始终返回
HTTP 404。 - 提供有意义的提示:告诉用户“资源未找到”或提供导航建议。
主流框架实现示例
Spring Boot(Java/Kotlin)
通过 @ControllerAdvice 或 ErrorController 捕获。
// 方式一:全局异常处理(推荐)
@ControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(NoHandlerFoundException.class)
@ResponseStatus(HttpStatus.NOT_FOUND)
public ResponseEntity<Map<String, Object>> handleNotFound(NoHandlerFoundException ex) {
Map<String, Object> body = new HashMap<>();
body.put("status", 404);
body.put("error", "Not Found");
body.put("path", ex.getRequestURL());
body.put("message", "请求的路径 " + ex.getRequestURL() + " 不存在");
return ResponseEntity.status(404).body(body);
}
}
// 方式二:在配置中启用 DispatcherServlet 抛出异常(否则 Spring Boot 会静默处理)
// 在 application.properties 中配置:
// spring.mvc.throw-exception-if-no-handler-found=true
// spring.web.resources.add-mappings=false
Django(Python) 通过自定义 404 视图处理。
# urls.py
from django.conf.urls import handler404
# 定义视图函数
def my_custom_page_not_found_view(request, exception):
return render(request, '404.html', status=404)
# 将处理器绑定到handler404
handler404 = my_custom_page_not_found_view
Express(Node.js) 在路由中间件末尾添加一个全匹配的“兜底”中间件。
// 在所有路由定义之后,添加这个中间件
app.use((req, res, next) => {
res.status(404).json({
status: 'error',
message: `路由 ${req.originalUrl} 未找到`,
data: null
});
});
前端单页应用(SPA)
前端路由未找到通常发生在用户手动输入 URL、刷新页面或点击了不存在的链接时。
核心挑战:服务端与客户端路由冲突
-
问题:用户在浏览器刷新
https://example.com/user/123,请求会先发给后端服务器,如果后端没有处理/user/*的路由,会直接返回 404,导致 SPA 无法加载。 -
解决方案(后端配合):将后端未匹配的路由全部指向
index.html(SPA 入口),然后在前端处理路由匹配。-
Nginx 配置:
location / { try_files $uri $uri/ /index.html; # 核心:如果找不到文件,则返回 index.html } -
Node.js(Express)配置:
// 必须放在所有 API 路由之后 app.get('*', (req, res) => { res.sendFile(path.join(__dirname, 'dist', 'index.html')); });
-
前端框架内处理
Vue Router
const routes = [
// ... 你的正常路由
{ path: '/:pathMatch(.*)*', name: 'NotFound', component: NotFoundComponent }
// 注意:Vue Router 4 中使用 pathMatch,3 中使用 catchAll
];
React Router
<Routes>
<Route path="/" element={<Home />} />
<Route path="/users/:id" element={<User />} />
{/* 兜底路由:放在最后 */}
<Route path="*" element={<NotFound />} />
</Routes>
Angular
const routes: Routes = [
{ path: '', component: HomeComponent },
{ path: '**', component: NotFoundComponent } // 通配符路由
];
HTTP API 服务
对于纯 API 服务(返回 JSON/XML),处理方式应更严格。
-
明确告知:返回一个标准化 JSON 结构。
{ "status": 404, "code": "ROUTE_NOT_FOUND", "message": "The requested endpoint '/api/invalid-path' does not exist.", "path": "/api/invalid-path", "timestamp": "2023-10-27T10:00:00Z" } -
拒绝 HTML 页面:API 请求头通常包含
Accept: application/json,后端应据此自动判断返回格式(如 Spring Boot 中的ContentNegotiationStrategy)。
-
分层处理:
- 网络层:Nginx 直接返回 404 静态页面(对静态资源请求)。
- 应用层:框架捕获
NotFound异常,返回 JSON(API)或友好页面(SPA 内)。
-
区分环境:
- 开发环境:显示详细错误信息(如 Django Debug=True)。
- 生产环境:显示通用提示,不泄露敏感信息。
-
日志记录:
记录未找到的路由 URL、用户代理、来源 IP,这有助于发现爬虫攻击、无效外链或配置错误。
-
提供“软导航”:
- 在前端 404 页面,提供:
- “返回首页”按钮
- “搜索”功能
- 最近更新的链接列表
- 这能显著降低因 404 导致的用户跳出率。
- 在前端 404 页面,提供:
-
SEO 优化:
- 确保 404 页面返回的是真实的 HTTP 404 状态码(而不是 200 但显示“未找到”),如果返回 200,搜索引擎可能会索引该页面为“未找到”,这很糟糕。
一句话建议
后端用全局异常处理 + 正确的 HTTP 状态码,前端用兜底路由组件 + 良好的用户交互,两端共同确保“404 也能被优雅对待”。