Angular Universal+Firebase SSR:404路由跳转遇403错误求助
解决Angular Universal + Firebase Cloud SSR下403错误与404页面跳转问题
咱们先理清楚核心问题:你的Angular路由已经配置了**重定向到404页面,但访问不存在的路由时返回403,这大概率是Firebase Hosting的重写规则没配对,再加上SSR服务端的状态码处理缺失导致的。结合你的代码,一步步来调整:
1. 先搞定Firebase Hosting的重写规则(关键!)
Firebase Hosting如果没把所有请求都转发到你的SSR云函数,就会对未匹配的路由返回403。打开你的firebase.json,确保重写规则正确:
{ "hosting": { "public": "dist/ricicla-risparmia-rinnova/browser", "ignore": [ "firebase.json", "**/.*", "**/node_modules/**" ], "rewrites": [ { "source": "**", "function": "ssr" // 这里要和你定义的SSR云函数名称一致 } ] }, "functions": { "source": "functions", "runtime": "nodejs18" // 确保Node版本和项目兼容 } }
划重点:必须让所有请求都走SSR函数,这样Angular的路由才能接管处理,不然Firebase会自己拦截未匹配的请求返回403。
2. 调整server.ts的状态码处理逻辑
你的server.ts现在对所有*路由直接渲染index.html,但没给404页面返回正确的HTTP状态码,Firebase会默认返回错误状态。修改这部分代码:
server.get('*', (req, res) => { res.render(indexHtml, { req, providers: [{provide: APP_BASE_HREF, useValue: req.baseUrl}] }, (err, html) => { // 判断是否渲染到了404页面,或者渲染出错 if (err || html.includes('NotFoundComponent')) { res.status(404).send(html); } else { res.send(html); } }); });
如果你想更精准判断路由是否存在,可以用Angular的Router在服务端预校验:
// 先在server.ts顶部导入依赖 import { Router } from '@angular/router'; import { AppServerModule } from './src/main.server'; // 修改路由处理逻辑 server.get('*', (req, res) => { const router = AppServerModule.injector.get(Router); router.navigateByUrl(req.url).then(success => { if (success) { res.render(indexHtml, { req, providers: [{provide: APP_BASE_HREF, useValue: req.baseUrl}] }); } else { // 路由不存在,返回404状态码+页面 res.status(404).render(indexHtml, { req, providers: [{provide: APP_BASE_HREF, useValue: req.baseUrl}] }); } }).catch(() => { res.status(404).send('Page not found'); }); });
3. 确认Angular路由配置的正确性
你的app-routing.module.ts配置本身没问题,但要注意两个细节:
NotFoundComponent必须正确导入并在对应模块中声明{path: '**', redirectTo: '404'}一定要放在所有路由的最后,保证它是最后匹配的规则
4. 重新部署生效
改完配置和代码后,必须重新构建+部署:
# 构建Angular Universal项目 npm run build:ssr # 部署Firebase函数和托管服务 firebase deploy --only functions,hosting
额外排查点
- 去Firebase控制台看云函数的日志,有没有报错信息,能帮你快速定位问题
- 确保
NotFoundComponent里没有依赖客户端专属API(比如window),不然SSR渲染时会出错,导致返回错误状态码
内容的提问来源于stack exchange,提问作者Luca Ognissante
相关产品推荐
相关产品推荐

