You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 07:19:48