Angular懒加载子路由访问时持续出现404错误求助
Angular懒加载子路由404问题排查
问题背景
尝试在Angular中实现带懒加载的子路由,但访问相关路径时始终出现404错误。非父子结构的路由功能正常,已确认模块和组件导入正确,懒加载模块路径无误。
相关代码
根路由配置(app-routing.module.ts)
{ path: 'reporting', loadChildren: () => import('./reservations/reporting/reporting.module').then(m => m.ReportingModule) } @NgModule({ imports: [RouterModule.forRoot(routes)], exports: [RouterModule] }) export class AppRoutingModule { }
子模块路由配置(reporting模块)
const routes: Routes = [ { path: '', component: ReportRoomComponent, children: [ { path: 'list', component: ReportListComponent }, { path: 'update/:id', component: UpdateReportsComponent }, ] } ]; @NgModule({ imports: [RouterModule.forChild(routes)], exports: [RouterModule] }) export class ReportingRoutingModule { }
组件HTML代码
ReportRoom组件
<router-outlet> <div class="content-page"> <div class="content"> <div class="site-section"> <div class="container"> <div class="row"> <div class="col-lg-7"> <form [formGroup]="reportForm" (ngSubmit)="onSubmit()"> <!-- Chambre Selection --> <div class="form-group"> <label for="numeroChambre" class="form-label">Numéro Chambre:</label> <select formControlName="chambre" id="numeroChambreSelect" class="form-control" required> <option value="" disabled selected>Choisissez une chambre</option> <option *ngFor="let room of allRooms" [value]="room.idChambre">{{ room }}</option> </select> <div *ngIf="reportForm.controls['chambre'].touched "> <small class="form-text text-danger" *ngIf="reportForm.controls['chambre'].errors?.['required']"> The room number is required. </small> </div> </div> <!-- Problem Type Selection --> <div class="form-group"> <label for="problemType" class="form-label">Type de problème:</label> <select formControlName="problem" id="problemTypeSelect" class="form-control" required> <option value="" disabled selected>Choisissez le type de problème</option> <option value="BINOME">BINOME</option> <option value="CHAUFFAGE">CHAUFFAGE</option> <option value="EAU">EAU</option> <option value="GAZ">GAZ</option> <option value="AUTRE">AUTRE</option> </select> <div *ngIf="reportForm.controls['problem'].touched "> <small class="form-text text-danger" *ngIf="reportForm.controls['problem'].errors?.['required']"> you have to choose the problem type please </small> </div> </div> <!-- Description Input --> <div class="form-group"> <label for="description" class="form-label">Description:</label> <input formControlName="description" type="text" class="form-control" placeholder="Description" name="description"> <div *ngIf="reportForm.controls['description'].touched "> <small class="form-text text-danger" *ngIf="reportForm.controls['description'].errors?.['required']"> Description is required. </small> <small class="form-text text-danger" *ngIf="reportForm.controls['description'].errors?.['minlength']"> Description must be at least 10 characters long. </small> <small class="form-text text-danger" *ngIf="reportForm.controls['description'].errors?.['maxlength']"> Description cannot be more than 20 characters long. </small> <small class="form-text text-danger" *ngIf="reportForm.controls['description'].errors?.['pattern']"> Description can only contain letters, numbers, and spaces. </small> </div> </div> <!-- Date of Report Input --> <div class="form-group"> <label for="dateReport" class="form-label">Date of Report:</label> <input formControlName="dateReport" type="date" class="form-control" placeholder="Date of Report" name="dateReport"> </div> <!-- Submit Button --> <div class="form-group"> <input type="submit" class="btn btn-primary py-3 px-5" value="Submit Report"> </div> </form> </div> </div> </div> </div> </div> </div> </router-outlet>
ReportList组件
<div class="content-page"> <div class="content"> <div class="container"> <div class="my-4"> <h2 class="mb-4">Liste des Report</h2> <div class="table-responsive"> <table class="table table table-strip"> <thead class="thead-dark"> <tr> <th>ID</th> <th>Probleme</th> <th>Description</th> <th>Date report</th> <th>Actions</th> </tr> </thead> <tbody> <tr *ngFor="let report of reports"> <td>{{ report.id }}</td> <td>{{ report.problem }}</td> <td>{{ report.description }}</td> <td>{{ report.dateReport }}</td> <td> <button class="btn btn-outline-success" (click)="navigate(report.id)">✔ Modifier</button> <button class="btn btn-outline-danger" (click)="deleteReport(report.id)">✘ Supprimer</button> </td> </tr> </tbody> </table> </div> </div> </div> </div> </div> <router-outlet></router-outlet>
排查与解决方向
修正路由出口位置
ReportRoom组件中错误地将所有内容包裹在<router-outlet>标签内,这会导致Angular无法正确识别子路由的渲染出口。正确的写法应该将<router-outlet>放在内容之外,比如:<div class="content-page"> <!-- 原有表单内容 --> </div> <router-outlet></router-outlet>子路由组件(如ReportList)会渲染在这个出口中,而不是覆盖父组件内容。
确认访问路径正确性
根据路由配置,正确的访问路径应为:/reporting:加载ReportRoom组件/reporting/list:同时加载ReportRoom和ReportList组件/reporting/update/:id:同时加载ReportRoom和UpdateReports组件
检查访问时的URL是否符合上述规则,避免拼写错误或路径层级错误。
验证懒加载路径准确性
再次确认loadChildren中的文件路径与项目实际文件结构一致,注意大小写(Linux/macOS环境下路径区分大小写),确保reporting.module.ts文件存在于指定目录。检查子模块路由导入
确保ReportingModule中已正确导入ReportingRoutingModule,且没有重复配置路由规则,避免路由冲突。生产环境服务器配置
如果是部署后出现404,需确保服务器支持HTML5路由模式:- Apache:配置
.htaccess文件添加重写规则 - Nginx:在配置文件中设置
try_files $uri $uri/ /index.html;
- Apache:配置
内容的提问来源于stack exchange,提问作者eya joma
相关产品推荐
相关产品推荐

