解决Actix-web多服务配置后第二个服务404 NotFound问题
问题:Actix-Web 为不同API配置文件上传大小限制后出现404错误
我在使用Actix-Web时希望为每个API单独限制文件上传大小,因此对原有单服务配置进行了拆分调整,但拆分后只有第一个服务配置生效,第二个URL上传时出现404 NotFound错误。调整scope名称后问题仍未解决。
原有调整后的代码(第一种写法):
pub fn config(cfg: &mut web::ServiceConfig) { cfg.service( web::scope("/tex/project") .route("/list", web::get().to(get_projects)) .route("/copy", web::post().to(cp_proj)), ); cfg.app_data( MultipartFormConfig::default() .total_limit(1048576) // 1 MB = 1024 * 1024 .memory_limit(2097152) // 2 MB = 2 * 1024 * 1024 .error_handler(handle_multipart_error), ) .service(web::scope("/tex/project").route("/upload", web::post().to(upload_full_proj))); cfg.app_data( MultipartFormConfig::default() .total_limit(104857600) // 100 MB = 100 * 1024 * 1024 .memory_limit(209715200) // 200 MB = 200 * 1024 * 1024 .error_handler(handle_multipart_error), ) .service(web::scope("/tex/project").route("/file/upload", web::post().to(upload_proj_file))); }
调整scope名称后的代码(第二种写法):
pub fn config(cfg: &mut web::ServiceConfig) { cfg.service( web::scope("/tex/project") .route("/list", web::get().to(get_projects)) .route("/copy", web::post().to(cp_proj)), ); cfg.app_data( MultipartFormConfig::default() .total_limit(1048576) // 1 MB = 1024 * 1024 .memory_limit(2097152) // 2 MB = 2 * 1024 * 1024 .error_handler(handle_multipart_error), ) .service(web::scope("/tex/project/proj").route("/upload", web::post().to(upload_full_proj))); cfg.app_data( MultipartFormConfig::default() .total_limit(104857600) // 100 MB = 100 * 1024 * 1024 .memory_limit(209715200) // 200 MB = 200 * 1024 * 1024 .error_handler(handle_multipart_error), ) .service(web::scope("/tex/project/file").route("/upload", web::post().to(upload_proj_file))); }
解决方案
问题出在全局app_data的覆盖逻辑:每次调用cfg.app_data()都会覆盖全局的配置,而不是为后续的service单独绑定配置。同时,重复创建相同scope会导致路由注册冲突或覆盖,进而引发404。
正确的做法是将MultipartFormConfig绑定到对应的scope或单个route上,确保每个接口拥有独立的上传限制配置:
方案一:统一在基础scope下配置各路由的独立规则
pub fn config(cfg: &mut web::ServiceConfig) { // 统一管理所有/tex/project下的路由 cfg.service( web::scope("/tex/project") .route("/list", web::get().to(get_projects)) .route("/copy", web::post().to(cp_proj)) // 为/upload接口绑定专属上传限制 .route( "/upload", web::post() .app_data( MultipartFormConfig::default() .total_limit(1048576) // 1MB .memory_limit(2097152) // 2MB .error_handler(handle_multipart_error), ) .to(upload_full_proj), ) // 为/file/upload接口绑定专属上传限制 .route( "/file/upload", web::post() .app_data( MultipartFormConfig::default() .total_limit(104857600) // 100MB .memory_limit(209715200) // 200MB .error_handler(handle_multipart_error), ) .to(upload_proj_file), ), ); }
方案二:拆分scope并为每个子scope绑定独立配置
pub fn config(cfg: &mut web::ServiceConfig) { // 基础路由集合 cfg.service( web::scope("/tex/project") .route("/list", web::get().to(get_projects)) .route("/copy", web::post().to(cp_proj)), ); // 项目上传专属scope,绑定对应配置 cfg.service( web::scope("/tex/project") .app_data( MultipartFormConfig::default() .total_limit(1048576) .memory_limit(2097152) .error_handler(handle_multipart_error), ) .route("/upload", web::post().to(upload_full_proj)), ); // 文件上传专属scope,绑定对应配置 cfg.service( web::scope("/tex/project/file") .app_data( MultipartFormConfig::default() .total_limit(104857600) .memory_limit(209715200) .error_handler(handle_multipart_error), ) .route("/upload", web::post().to(upload_proj_file)), ); }
关键说明
app_data()的作用域是它所属的ServiceConfig、Scope或Route,全局调用cfg.app_data()会覆盖之前的全局配置,导致后续服务使用最后一次设置的规则,同时可能因路由注册冲突引发404。- 将配置绑定到具体的
Route或Scope上,才能确保每个接口使用独立的上传限制,同时避免路由覆盖问题。
内容的提问来源于stack exchange,提问作者Dolphin
相关产品推荐
相关产品推荐

