angular - 角度路由在生产构建中不起作用
问题描述
我正在开发一个 Angular 项目,它是一个带有登录页面的网络应用程序。该项目配置为在命中基本 URL 时显示登录,并在尝试访问会话中没有有效令牌的应用程序时重定向到登录页面。
该应用程序包含在其自己的模块中,该模块执行所有内部路由。
在这两种情况下一切正常:
ng serve
ng build
npx lite-server --baseDir="dist/frontend"
然后在使用生产标志构建时,路由中断。以下两种方式的行为相同:
ng build --prod
npx lite-server --baseDir="dist/frontend"
ng build --prod
firebase deploy
当我尝试访问“客户端”模块 ( http://host/client/anything ) 中的任何内容时,应用程序会再次将我重定向到着陆点 ( http://host/landing ),无论如何,如果粘贴 URL在浏览器栏中或通过登陆中的控件访问。
我已经阅读了用于部署的 Angular 文档,但在我的案例中已经配置了提到的提示。在那里阅读其他类似的堆栈帖子我找不到解决方案。
到目前为止我尝试了什么:
- 在路由中使用哈希:
imports: [RouterModule.forRoot(routes, { useHash: true })]
- 禁用构建优化器和aot:
ng build --prod --build-optimizer=false --aot=false
- 检查服务器配置。
index.html
后备是好的
启用跟踪让我看到路由器确实在尝试访问登录页面,但是我没有得到的东西在中间中断。生产构建跟踪是:
main-es2015.4665a3d5fdcea262528d.js:1 路由器事件:Ee main-es2015.4665a3d5fdcea262528d.js:1 NavigationStart(id: 5, url: '/client') main-es2015.4665a3d5fdcea262528d.js:1 Ee {id:5,url:“/client”,navigationTrigger:“imperative”,restoredState:null}id:5navigationTrigger:“imperative”restoredState:nullurl:“/client”__proto__:我们 main-es2015.4665a3d5fdcea262528d.js:1 路由器事件:重新 main-es2015.4665a3d5fdcea262528d.js:1 RoutesRecognized(id: 5, url: '/client', urlAfterRedirects: '/client', state: Route(url:'', path:'') { Route(url:'client ', path:'client') { Route(url:'', path:'') } } ) main-es2015.4665a3d5fdcea262528d.js:1 Re {id: 5, url: "/client", urlAfterRedirects: "/client", state: At} main-es2015.4665a3d5fdcea262528d.js:1 路由器事件:Oe main-es2015.4665a3d5fdcea262528d.js:1 GuardsCheckStart(id: 5, url: '/client', urlAfterRedirects: '/client', state: Route(url:'', path:'') { Route(url:'client ', path:'client') { Route(url:'', path:'') } } ) main-es2015.4665a3d5fdcea262528d.js:1 Oe {id: 5, url: "/client", urlAfterRedirects: "/client", state: At} main-es2015.4665a3d5fdcea262528d.js:1 路由器事件:xe main-es2015.4665a3d5fdcea262528d.js:1 ChildActivationStart(路径:'') main-es2015.4665a3d5fdcea262528d.js:1 xe {快照:Tt} main-es2015.4665a3d5fdcea262528d.js:1 路由器事件:Fe main-es2015.4665a3d5fdcea262528d.js:1 ActivationStart(路径:'client') main-es2015.4665a3d5fdcea262528d.js:1 Fe {snapshot: Tt} main-es2015.4665a3d5fdcea262528d.js:1 路由器事件:_e main-es2015.4665a3d5fdcea262528d.js:1 NavigationCancel(id: 5, url: '/client') main-es2015.4665a3d5fdcea262528d.js:1 _e {id: 5, url: "/client", reason: "导航 ID 5 不等于当前导航 ID 6"} main-es2015.4665a3d5fdcea262528d.js:1 路由器事件:Ee main-es2015.4665a3d5fdcea262528d.js:1 NavigationStart(id: 6, url: '/login?returnUrl=%2Fclient') main-es2015.4665a3d5fdcea262528d.js:1 Ee {id: 6, url: "/login?returnUrl=%2Fclient", navigationTrigger: "imperative", restoreState: null} main-es2015.4665a3d5fdcea262528d.js:1 路由器事件:重新 main-es2015.4665a3d5fdcea262528d.js:1 RoutesRecognized(id: 6, url: '/login?returnUrl=%2Fclient', urlAfterRedirects: '/login?returnUrl=%2Fclient', state: Route(url:'', path: '') { Route(url:'login', path:'login') } ) main-es2015.4665a3d5fdcea262528d.js:1 Re {id: 6, url: "/login?returnUrl=%2Fclient", urlAfterRedirects: "/login?returnUrl=%2Fclient", state: At} main-es2015.4665a3d5fdcea262528d.js:1 路由器事件:Oe main-es2015.4665a3d5fdcea262528d.js:1 GuardsCheckStart(id: 6, url: '/login?returnUrl=%2Fclient', urlAfterRedirects: '/login?returnUrl=%2Fclient', state: Route(url:'', path: '') { Route(url:'login', path:'login') } ) main-es2015.4665a3d5fdcea262528d.js:1 Oe {id: 6, url: "/login?returnUrl=%2Fclient", urlAfterRedirects: "/login?returnUrl=%2Fclient", 状态: At} main-es2015.4665a3d5fdcea262528d.js:1 路由器事件:xe main-es2015.4665a3d5fdcea262528d.js:1 ChildActivationStart(路径:'') main-es2015.4665a3d5fdcea262528d.js:1 xe {快照:Tt} main-es2015.4665a3d5fdcea262528d.js:1 路由器事件:Fe main-es2015.4665a3d5fdcea262528d.js:1 ActivationStart(路径:'登录') main-es2015.4665a3d5fdcea262528d.js:1 Fe {snapshot: Tt} main-es2015.4665a3d5fdcea262528d.js:1 路由器事件:De main-es2015.4665a3d5fdcea262528d.js:1 GuardsCheckEnd(id: 6, url: '/login?returnUrl=%2Fclient', urlAfterRedirects: '/login?returnUrl=%2Fclient', state: Route(url:'', path: '') { Route(url:'login', path:'login') } , shouldActivate: true) main-es2015.4665a3d5fdcea262528d.js:1 De {id: 6, url: "/login?returnUrl=%2Fclient", urlAfterRedirects: "/login?returnUrl=%2Fclient", state: At, shouldActivate: true} main-es2015.4665a3d5fdcea262528d.js:1 路由器事件:Pe main-es2015.4665a3d5fdcea262528d.js:1 ResolveStart(id: 6, url: '/login?returnUrl=%2Fclient', urlAfterRedirects: '/login?returnUrl=%2Fclient', state: Route(url:'', path: '') { Route(url:'login', path:'login') } ) main-es2015.4665a3d5fdcea262528d.js:1 Pe {id: 6, url: "/login?returnUrl=%2Fclient", urlAfterRedirects: "/login?returnUrl=%2Fclient", 状态: At} main-es2015.4665a3d5fdcea262528d.js:1 路由器事件:Te main-es2015.4665a3d5fdcea262528d.js:1 ResolveEnd(id: 6, url: '/login?returnUrl=%2Fclient', urlAfterRedirects: '/login?returnUrl=%2Fclient', state: Route(url:'', path: '') { Route(url:'login', path:'login') } ) main-es2015.4665a3d5fdcea262528d.js:1 Te {id: 6, url: "/login?returnUrl=%2Fclient", urlAfterRedirects: "/login?returnUrl=%2Fclient", 状态: At} main-es2015.4665a3d5fdcea262528d.js:1 路由器事件:_e main-es2015.4665a3d5fdcea262528d.js:1 NavigationCancel(id: 6, url: '/login?returnUrl=%2Fclient') main-es2015.4665a3d5fdcea262528d.js:1 _e {id: 6, url: "/login?returnUrl=%2Fclient", 原因: "导航 ID 6 不等于当前导航 ID 7"} main-es2015.4665a3d5fdcea262528d.js:1 路由器事件:Ee main-es2015.4665a3d5fdcea262528d.js:1 NavigationStart(id: 7, url: '/') main-es2015.4665a3d5fdcea262528d.js:1 Ee {id: 7, url: "/", navigationTrigger: "imperative", restoreState: null} main-es2015.4665a3d5fdcea262528d.js:1 路由器事件:我 main-es2015.4665a3d5fdcea262528d.js:1 ActivationEnd(路径:'登录') main-es2015.4665a3d5fdcea262528d.js:1 我{快照:Tt} main-es2015.4665a3d5fdcea262528d.js:1 路由器事件:Ne main-es2015.4665a3d5fdcea262528d.js:1 ChildActivationEnd(路径:'') main-es2015.4665a3d5fdcea262528d.js:1 Ne {快照:Tt} main-es2015.4665a3d5fdcea262528d.js:1 路由器事件:重新 main-es2015.4665a3d5fdcea262528d.js:1 RoutesRecognized(id: 7, url: '/', urlAfterRedirects: '/landing', state: Route(url:'', path:'') { Route(url:'landing' , 路径:'着陆') } ) main-es2015.4665a3d5fdcea262528d.js:1 Re {id: 7, url: "/", urlAfterRedirects: "/landing", state: At} main-es2015.4665a3d5fdcea262528d.js:1 路由器事件:Oe main-es2015.4665a3d5fdcea262528d.js:1 GuardsCheckStart(id: 7, url: '/', urlAfterRedirects: '/landing', state: Route(url:'', path:'') { Route(url:'landing' , 路径:'着陆') } ) main-es2015.4665a3d5fdcea262528d.js:1 Oe {id: 7, url: "/", urlAfterRedirects: "/landing", state: At} main-es2015.4665a3d5fdcea262528d.js:1 路由器事件:xe main-es2015.4665a3d5fdcea262528d.js:1 ChildActivationStart(路径:'') main-es2015.4665a3d5fdcea262528d.js:1 xe {快照:Tt} main-es2015.4665a3d5fdcea262528d.js:1 路由器事件:Fe main-es2015.4665a3d5fdcea262528d.js:1 ActivationStart(路径:'登陆') main-es2015.4665a3d5fdcea262528d.js:1 Fe {snapshot: Tt} main-es2015.4665a3d5fdcea262528d.js:1 路由器事件:De main-es2015.4665a3d5fdcea262528d.js:1 GuardsCheckEnd(id: 7, url: '/', urlAfterRedirects: '/landing', state: Route(url:'', path:'') { Route(url:'landing' , path:'landing') } , shouldActivate: true) main-es2015.4665a3d5fdcea262528d.js:1 De {id: 7, url: "/", urlAfterRedirects: "/landing", state: At, shouldActivate: true} main-es2015.4665a3d5fdcea262528d.js:1 路由器事件:Pe main-es2015.4665a3d5fdcea262528d.js:1 ResolveStart(id: 7, url: '/', urlAfterRedirects: '/landing', state: Route(url:'', path:'') { Route(url:'landing' , 路径:'着陆') } ) main-es2015.4665a3d5fdcea262528d.js:1 Pe {id: 7, url: "/", urlAfterRedirects: "/landing", state: At} main-es2015.4665a3d5fdcea262528d.js:1 路由器事件:Te main-es2015.4665a3d5fdcea262528d.js:1 ResolveEnd(id: 7, url: '/', urlAfterRedirects: '/landing', state: Route(url:'', path:'') { Route(url:'landing' , 路径:'着陆') } ) main-es2015.4665a3d5fdcea262528d.js:1 Te {id: 7, url: "/", urlAfterRedirects: "/landing", state: At} main-es2015.4665a3d5fdcea262528d.js:1 路由器事件:我 main-es2015.4665a3d5fdcea262528d.js:1 ActivationEnd(路径:'登陆') main-es2015.4665a3d5fdcea262528d.js:1 我{快照:Tt} main-es2015.4665a3d5fdcea262528d.js:1 路由器事件:Ne main-es2015.4665a3d5fdcea262528d.js:1 ChildActivationEnd(路径:'') main-es2015.4665a3d5fdcea262528d.js:1 Ne {快照:Tt} main-es2015.4665a3d5fdcea262528d.js:1 路由器事件:be main-es2015.4665a3d5fdcea262528d.js:1 NavigationEnd(id: 7, url: '/', urlAfterRedirects: '/landing') main-es2015.4665a3d5fdcea262528d.js:1 是 {id: 7, url: "/", urlAfterRedirects: "/landing"} main-es2015.4665a3d5fdcea262528d.js:1 路由器事件:Le main-es2015.4665a3d5fdcea262528d.js:1 滚动(锚点:'null',位置:'null') main-es2015.4665a3d5fdcea262528d.js:1 Le {routerEvent: be, position: null, anchor: null}
导航被取消两次。第一个应该是因为 auth-guard 在尝试获取“客户端”模块时返回 false ,但根据记录的原因似乎是另一个原因。
开发构建跟踪完全不同:
platform-browser.js:96 路由器事件:NavigationStart platform-browser.js:87 NavigationStart(id: 5, url: '/client') platform-browser.js:87 NavigationStart {id: 5, url: "/client", navigationTrigger: "imperative", restoreState: null} 路由器事件:RoutesRecognized RoutesRecognized(id: 5, url: '/client', urlAfterRedirects: '/client', state: Route(url:'', path:'') { Route(url:'client', path:'client') { 路线(网址:'',路径:'')} }) RoutesRecognized {id: 5, url: "/client", urlAfterRedirects: "/client", state: RouterStateSnapshot} 路由器事件:GuardsCheckStart GuardsCheckStart(id: 5, url: '/client', urlAfterRedirects: '/client', state: Route(url:'', path:'') { Route(url:'client', path:'client') { 路线(网址:'',路径:'')} }) GuardsCheckStart {id: 5, url: "/client", urlAfterRedirects: "/client", state: RouterStateSnapshot} 路由器事件:ChildActivationStart ChildActivationStart(路径:'') ChildActivationStart {快照:ActivatedRouteSnapshot} 路由器事件:ActivationStart ActivationStart(路径:'客户端') ActivationStart {快照:ActivatedRouteSnapshot} 路由器事件:NavigationCancel NavigationCancel(id: 5, url: '/client') NavigationCancel {id: 5, url: "/client", reason: "导航ID 5不等于当前导航id 6"} 路由器事件:NavigationStart NavigationStart(id: 6, url: '/login?returnUrl=%2Fclient') NavigationStart {id: 6, url: "/login?returnUrl=%2Fclient", navigationTrigger: "imperative", restoreState: null} 路由器事件:RoutesRecognized RoutesRecognized(id: 6, url: '/login?returnUrl=%2Fclient', urlAfterRedirects: '/login?returnUrl=%2Fclient', state: Route(url:'', path:'') { Route(url: '登录',路径:'登录')}) RoutesRecognized {id: 6, url: "/login?returnUrl=%2Fclient", urlAfterRedirects: "/login?returnUrl=%2Fclient", state: RouterStateSnapshot} 路由器事件:GuardsCheckStart GuardsCheckStart(id: 6, url: '/login?returnUrl=%2Fclient', urlAfterRedirects: '/login?returnUrl=%2Fclient', state: Route(url:'', path:'') { Route(url: '登录',路径:'登录')}) GuardsCheckStart {id: 6, url: "/login?returnUrl=%2Fclient", urlAfterRedirects: "/login?returnUrl=%2Fclient", state: RouterStateSnapshot} 路由器事件:ChildActivationStart platform-browser.js:87 ChildActivationStart(路径:'') platform-browser.js:87 ChildActivationStart {快照:ActivatedRouteSnapshot} platform-browser.js:96 路由器事件:ActivationStart platform-browser.js:87 ActivationStart(路径:'登录') platform-browser.js:87 ActivationStart {快照:ActivatedRouteSnapshot} platform-browser.js:96 路由器事件:GuardsCheckEnd platform-browser.js:87 GuardsCheckEnd(id: 6, url: '/login?returnUrl=%2Fclient', urlAfterRedirects: '/login?returnUrl=%2Fclient', state: Route(url:'', path:'' ) { Route(url:'login', path:'login') } , shouldActivate: true) platform-browser.js:87 GuardsCheckEnd {id: 6, url: "/login?returnUrl=%2Fclient", urlAfterRedirects: "/login?returnUrl=%2Fclient", state: RouterStateSnapshot, shouldActivate: true} platform-browser.js:96 路由器事件:ResolveStart platform-browser.js:87 ResolveStart(id: 6, url: '/login?returnUrl=%2Fclient', urlAfterRedirects: '/login?returnUrl=%2Fclient', state: Route(url:'', path:'' ) { 路由(url:'login', path:'login') }) platform-browser.js:87 ResolveStart {id: 6, url: "/login?returnUrl=%2Fclient", urlAfterRedirects: "/login?returnUrl=%2Fclient", state: RouterStateSnapshot} platform-browser.js:96 路由器事件:ResolveEnd platform-browser.js:87 ResolveEnd(id: 6, url: '/login?returnUrl=%2Fclient', urlAfterRedirects: '/login?returnUrl=%2Fclient', state: Route(url:'', path:'' ) { 路由(url:'login', path:'login') }) platform-browser.js:87 ResolveEnd {id: 6, url: "/login?returnUrl=%2Fclient", urlAfterRedirects: "/login?returnUrl=%2Fclient", state: RouterStateSnapshot} platform-browser.js:96 路由器事件:ActivationEnd platform-browser.js:87 ActivationEnd(路径:'登录') platform-browser.js:87 ActivationEnd {快照:ActivatedRouteSnapshot} platform-browser.js:96 路由器事件:ChildActivationEnd platform-browser.js:87 ChildActivationEnd(路径:'') platform-browser.js:87 ChildActivationEnd {快照:ActivatedRouteSnapshot} platform-browser.js:96 路由器事件:NavigationEnd platform-browser.js:87 NavigationEnd(id: 6, url: '/login?returnUrl=%2Fclient', urlAfterRedirects: '/login?returnUrl=%2Fclient') platform-browser.js:87 NavigationEnd {id: 6, url: "/login?returnUrl=%2Fclient", urlAfterRedirects: "/login?returnUrl=%2Fclient"} platform-browser.js:96 路由器事件:滚动
任何帮助表示赞赏。提前致谢。
解决方案
如果您使用 firebase 托管来托管您的构建,则需要启用对 index.html 的重写。
您可以通过添加以下部分在 firebase.json 文件中执行此操作rewrites
:
{
"hosting": {
"public": "dist/browser",
"rewrites": [
{
"source": "**",
"destination": "/index.html"
}
],
...
}
}
推荐阅读
- excel - excel 2016 将小计与 sumifs 结合起来
- sql-server - 无法连接到家庭网络上的 SQL Server 2019
- bash - 获取输出到 /dev/null 的命令的执行时间
- python - 如何在 Python、Octave 或 Matlab 中求解这个非线性方程?
- azure-iot-edge - 如何在 Windows 上的 IoT Edge 中使用工作负载 uri 和 management_uri
- python - paramiko 键盘 仅限交互式身份验证
- ruby-on-rails - 如何在我的 rails 应用程序中捕获命令行/linux 命令并将输出存储在变量中?
- python - 十六进制值的 Bigram
- android - Flutter:限制应用程序中的屏幕捕获
- c++ - 在 C++ 中乘以单个位值