Angular中如何让博客详情页触发404错误?
问题分析与解决方案
问题核心在于blog/:slug是动态参数路由,任何以blog/开头的路径都会匹配该路由——哪怕slug对应的博客不存在,也会加载BlogDetailComponent而非NotFoundComponent。以下是具体解决步骤:
1. 补全路由的404通配符配置
将通配符路由放在所有路由的最后,确保只有未匹配到前面路由的请求才会触发404:
const routes: Routes = [ { path: 'contact', component: ContactComponent }, { path: 'blog', component: BlogComponent }, { path: 'blog/:slug', component: BlogDetailComponent }, // 通配符路由必须放最后,拦截所有未匹配路径 { path: '**', component: NotFoundComponent } ];
2. 在BlogDetailComponent中校验slug有效性
组件加载时,根据slug请求博客数据,若数据不存在(或接口返回404),手动跳转至404页面:
import { Component, OnInit } from '@angular/core'; import { ActivatedRoute, Router } from '@angular/router'; import { BlogService } from '../blog.service'; @Component({ selector: 'app-blog-detail', templateUrl: './blog-detail.component.html', styleUrls: ['./blog-detail.component.css'] }) export class BlogDetailComponent implements OnInit { constructor( private route: ActivatedRoute, private router: Router, private blogService: BlogService ) {} ngOnInit(): void { const slug = this.route.snapshot.paramMap.get('slug'); if (slug) { this.blogService.getBlogBySlug(slug).subscribe({ next: (blog) => { // 渲染有效博客内容 }, error: (err) => { // 捕获404或数据不存在的情况,跳转至404页面 if (err.status === 404 || !err.error) { this.router.navigate(['/404']); } } }); } } }
3. 恢复Server.ts的默认配置
若之前修改Server.ts导致混乱,先恢复到标准配置。Angular Universal的Server.ts需确保所有路由返回index.html,由前端路由处理分发:
// Server.ts核心配置示例 import { APP_BASE_HREF } from '@angular/common'; import { ngExpressEngine } from '@nguniversal/express-engine'; import * as express from 'express'; import { existsSync } from 'fs'; import { join } from 'path'; import { AppServerModule } from './src/main.server'; const app = express(); const distFolder = join(process.cwd(), 'dist/your-project-name/browser'); const indexHtml = existsSync(join(distFolder, 'index.original.html')) ? 'index.original.html' : 'index'; app.engine('html', ngExpressEngine({ bootstrap: AppServerModule, })); app.set('view engine', 'html'); app.set('views', distFolder); // 静态资源路由 app.get('*.*', express.static(distFolder, { maxAge: '1y' })); // 所有路由返回index.html,交由Angular处理路由逻辑 app.get('*', (req, res) => { res.render(indexHtml, { req, providers: [{ provide: APP_BASE_HREF, useValue: req.baseUrl }] }); }); const port = process.env['PORT'] || 4000; app.listen(port, () => { console.log(`Node Express server listening on http://localhost:${port}`); });
内容的提问来源于stack exchange,提问作者user27023959
相关产品推荐
相关产品推荐

