如何为Angular 5通配符路由设置404状态码(SSR场景)
在Angular Universal SSR中为通配符路由设置404状态码的解决方案
我来帮你搞定这个问题!之前的方案没生效可能是某些细节没落实到位,下面是一套亲测有效的实现步骤:
1. 确保通配符路由配置正确(客户端+SSR共享)
首先在你的app-routing.module.ts里,把通配符路由放在所有路由的最后,确保只有当其他路由都匹配失败时才会进入404页面:
import { NgModule } from '@angular/core'; import { RouterModule, Routes } from '@angular/router'; import { NotFoundComponent } from './not-found/not-found.component'; // 导入你的其他业务组件 const routes: Routes = [ // 你的正常业务路由示例 { path: '', component: HomeComponent }, { path: 'detail/:id', component: DetailComponent }, // 通配符路由必须放在最后,作为兜底 { path: '**', component: NotFoundComponent } ]; @NgModule({ imports: [RouterModule.forRoot(routes)], exports: [RouterModule] }) export class AppRoutingModule { }
2. 在404组件中注入服务器端响应对象设置状态码
在NotFoundComponent中,我们需要判断当前是否处于服务器端渲染环境,然后直接修改响应的状态码:
import { Component, OnInit, Inject, PLATFORM_ID } from '@angular/core'; import { isPlatformServer } from '@angular/common'; import { RESPONSE } from '@nguniversal/express-engine/tokens'; import { Response } from 'express'; @Component({ selector: 'app-not-found', templateUrl: './not-found.component.html', styleUrls: ['./not-found.component.css'] }) export class NotFoundComponent implements OnInit { constructor( // 注入平台标识,判断是否为服务器端环境 @Inject(PLATFORM_ID) private platformId: Object, // 注入Express的Response对象(仅服务器端可用) @Inject(RESPONSE) private response: Response ) { } ngOnInit(): void { // 仅在服务器端渲染时设置404状态码 if (isPlatformServer(this.platformId)) { this.response.status(404); } } }
这里的RESPONSE token是Angular Universal自动提供的,只要你的server.ts是官方CLI生成的SSR模板,就不需要额外配置。
3. 调整server.ts的请求处理顺序(避免静态资源被路由接管)
在server.ts中,一定要先处理静态资源请求,再处理Angular路由请求,否则不存在的静态资源会被Angular路由拦截,导致状态码异常:
import 'zone.js/dist/zone-node'; import { ngExpressEngine } from '@nguniversal/express-engine'; import * as express from 'express'; import { join } from 'path'; import { AppServerModule } from './src/main.server'; import { APP_BASE_HREF } from '@angular/common'; const app = express(); const PORT = process.env.PORT || 4000; const DIST_FOLDER = join(process.cwd(), 'dist/your-project-name/browser'); const indexHtml = join(DIST_FOLDER, 'index.html'); // 第一步:优先处理静态资源请求(如JS、CSS、图片等) app.get('*.*', express.static(DIST_FOLDER, { maxAge: '1y' // 可选:设置静态资源缓存有效期 })); // 第二步:处理Angular路由请求 app.get('*', (req, res) => { res.render(indexHtml, { req, providers: [ { provide: APP_BASE_HREF, useValue: req.baseUrl } ] }); }); app.listen(PORT, () => { console.log(`Node Express server listening on http://localhost:${PORT}`); });
4. 验证效果
启动SSR服务后,用curl命令测试:
curl -I http://localhost:4000/any-non-existent-path
如果返回的响应头中包含HTTP/1.1 404 Not Found,就说明配置成功了!
常见坑点提醒
- 通配符路由必须放在所有路由的最后,否则会提前拦截正常路由。
- 确保
NotFoundComponent中没有其他逻辑覆盖响应状态码。 - 如果使用了自定义服务器端中间件,不要在中间件中修改响应状态码导致冲突。
内容的提问来源于stack exchange,提问作者sumit patil
相关产品推荐
相关产品推荐

