Angular v19 SSR中如何从组件修改响应HTTP状态码至404
Angular v19 SSR 404 HTTP状态码问题解决方案
能否在404页面组件内修改HTTP状态码?
不能。404组件的渲染逻辑执行时,SSR服务器已经开始发送HTTP响应头,此时无法再修改状态码(HTTP协议要求状态码必须在响应体前发送)。
正确实现方式
需要在服务器端响应生成前的逻辑中设置404状态码,推荐两种方案:
方案1:使用路由Resolve守卫预校验实体状态
在详情页的路由数据预加载阶段,判断实体是否存在,若不存在则直接在SSR环境下设置404状态码,再导航到404页面。
- 创建Resolve守卫:
import { Injectable } from '@angular/core'; import { Resolve, ActivatedRouteSnapshot, Router } from '@angular/router'; import { EntityService } from './entity.service'; import { NotFoundError } from '@angular/common/http'; import { catchError } from 'rxjs/operators'; import { of } from 'rxjs'; @Injectable({ providedIn: 'root' }) export class EntityResolve implements Resolve<any> { constructor(private entityService: EntityService, private router: Router) {} resolve(route: ActivatedRouteSnapshot) { const entityId = route.paramMap.get('id'); return this.entityService.getEntity(entityId).pipe( catchError(error => { if (error instanceof NotFoundError) { // 仅在SSR环境下操作响应对象 if (typeof window === 'undefined') { (global as any).response.statusCode = 404; } this.router.navigate(['/404']); return of(null); } throw error; }) ); } }
- 配置详情页路由:
const routes: Routes = [ { path: 'entity/:id', component: EntityDetailComponent, resolve: { entity: EntityResolve } }, { path: '404', component: NotFoundComponent } ];
方案2:在SSR服务器(Express)中判断并设置状态码
如果使用Express作为SSR服务器,可以在渲染回调中检查当前路由是否为404页面,再修改状态码。
修改server.ts中的渲染逻辑:
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 distFolder = join(process.cwd(), 'dist/your-project/browser'); app.engine('html', ngExpressEngine({ bootstrap: AppServerModule })); app.set('view engine', 'html'); app.set('views', distFolder); app.get('*', (req, res) => { res.render('index', { req, providers: [{ provide: APP_BASE_HREF, useValue: req.baseUrl }] }, (err, html) => { // 两种判断方式选其一: // 1. 直接匹配404路由路径 if (req.path === '/404') { res.status(404); } // 2. 检查渲染内容是否包含404组件特征(更灵活) // if (html.includes('NotFoundComponent')) { res.status(404); } res.send(html); }); }); app.listen(4000, () => { console.log('SSR server running on http://localhost:4000'); });
内容的提问来源于stack exchange,提问作者Bachir31
相关产品推荐
相关产品推荐

