Actix-web v4中如何编写Catch All路由?
Actix-web 实现Catch All路由的正确方式
问题原因
你遇到的Tail segments must have names错误,是因为Actix-router要求通配符尾段必须指定名称,不能直接用/*这种无命名的写法。
解决方法
将Catch All路由的路径改为/{tail:.*}(或遵循错误提示的.../{tail}*,前者在Actix-web中更常用),并且必须将该路由放在所有其他服务(比如Files、API路由)的最后——因为Actix-web按路由定义顺序匹配,前面的路由匹配成功后就不会执行后续路由。
修正后的完整代码:
async fn not_found() -> impl Responder { "404" } HttpServer::new(|| { App::new() // 先处理静态文件请求 .service(Files::new("/", "./").index_file("index.html")) // 匹配所有未被前面服务处理的GET请求 .route("/{tail:.*}", web::get().to(not_found)) }) .bind(("127.0.0.1", 8080))? .run() .await
扩展:匹配所有HTTP方法的404
如果需要处理所有未匹配的HTTP方法(GET、POST等),可以使用default_service替代route:
HttpServer::new(|| { App::new() .service(Files::new("/", "./").index_file("index.html")) // 匹配所有未被处理的请求(不限HTTP方法) .default_service(web::route().to(not_found)) }) .bind(("127.0.0.1", 8080))? .run() .await
注意事项
- 路由顺序至关重要:Catch All路由必须放在最后,否则会拦截前面所有服务的请求。
{tail:.*}中的tail是匹配段的名称,即使你不需要使用这个参数,也必须指定它,这是Actix-router的强制要求。
内容的提问来源于stack exchange,提问作者Karsten Rabe
相关产品推荐
相关产品推荐

