角路由在生产版本中不起作用

时间:2020-06-05 15:35:13

标签: angular router production

我正在开发一个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)中的任何内容时,无论如何,如果将URL粘贴到浏览器中,应用程序都会将我重定向到登陆页面(http://host/landing)栏或通过平台中的控件进行访问。

我已经阅读了Angular文档进行部署,但是在我的案例中已经配置了上面提到的技巧。 在那儿阅读其他类似的堆栈文章,我找不到解决方法。

到目前为止我尝试过的事情:

  • 在路由中使用哈希:imports: [RouterModule.forRoot(routes, { useHash: true })]
  • 禁用构建优化器和aot:ng build --prod --build-optimizer=false --aot=false
  • 检查服务器配置。 index.html可以使用后备广告

启用跟踪让我看到路由器确实在尝试访问登录页面,但是我没有得到的东西在中间中断了。生产构建跟踪为:

main-es2015.4665a3d5fdcea262528d.js:1 Router Event: 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__: we
main-es2015.4665a3d5fdcea262528d.js:1 Router Event: Re
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 Router Event: 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 Router Event: xe
main-es2015.4665a3d5fdcea262528d.js:1 ChildActivationStart(path: '')
main-es2015.4665a3d5fdcea262528d.js:1 xe {snapshot: Tt}
main-es2015.4665a3d5fdcea262528d.js:1 Router Event: Fe
main-es2015.4665a3d5fdcea262528d.js:1 ActivationStart(path: 'client')
main-es2015.4665a3d5fdcea262528d.js:1 Fe {snapshot: Tt}

main-es2015.4665a3d5fdcea262528d.js:1 Router Event: _e
main-es2015.4665a3d5fdcea262528d.js:1 NavigationCancel(id: 5, url: '/client')
main-es2015.4665a3d5fdcea262528d.js:1 _e {id: 5, url: "/client", reason: "Navigation ID 5 is not equal to the current navigation id 6"}

main-es2015.4665a3d5fdcea262528d.js:1 Router Event: 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", restoredState: null}
main-es2015.4665a3d5fdcea262528d.js:1 Router Event: Re
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 Router Event: 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", state: At}
main-es2015.4665a3d5fdcea262528d.js:1 Router Event: xe
main-es2015.4665a3d5fdcea262528d.js:1 ChildActivationStart(path: '')
main-es2015.4665a3d5fdcea262528d.js:1 xe {snapshot: Tt}
main-es2015.4665a3d5fdcea262528d.js:1 Router Event: Fe
main-es2015.4665a3d5fdcea262528d.js:1 ActivationStart(path: 'login')
main-es2015.4665a3d5fdcea262528d.js:1 Fe {snapshot: Tt}
main-es2015.4665a3d5fdcea262528d.js:1 Router Event: 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 Router Event: 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", state: At}
main-es2015.4665a3d5fdcea262528d.js:1 Router Event: 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", state: At}

main-es2015.4665a3d5fdcea262528d.js:1 Router Event: _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", reason: "Navigation ID 6 is not equal to the current navigation id 7"}

main-es2015.4665a3d5fdcea262528d.js:1 Router Event: Ee
main-es2015.4665a3d5fdcea262528d.js:1 NavigationStart(id: 7, url: '/')
main-es2015.4665a3d5fdcea262528d.js:1 Ee {id: 7, url: "/", navigationTrigger: "imperative", restoredState: null}
main-es2015.4665a3d5fdcea262528d.js:1 Router Event: Me
main-es2015.4665a3d5fdcea262528d.js:1 ActivationEnd(path: 'login')
main-es2015.4665a3d5fdcea262528d.js:1 Me {snapshot: Tt}
main-es2015.4665a3d5fdcea262528d.js:1 Router Event: Ne
main-es2015.4665a3d5fdcea262528d.js:1 ChildActivationEnd(path: '')
main-es2015.4665a3d5fdcea262528d.js:1 Ne {snapshot: Tt}
main-es2015.4665a3d5fdcea262528d.js:1 Router Event: Re
main-es2015.4665a3d5fdcea262528d.js:1 RoutesRecognized(id: 7, url: '/', urlAfterRedirects: '/landing', state: Route(url:'', path:'') { Route(url:'landing', path:'landing') } )
main-es2015.4665a3d5fdcea262528d.js:1 Re {id: 7, url: "/", urlAfterRedirects: "/landing", state: At}
main-es2015.4665a3d5fdcea262528d.js:1 Router Event: Oe
main-es2015.4665a3d5fdcea262528d.js:1 GuardsCheckStart(id: 7, url: '/', urlAfterRedirects: '/landing', state: Route(url:'', path:'') { Route(url:'landing', path:'landing') } )
main-es2015.4665a3d5fdcea262528d.js:1 Oe {id: 7, url: "/", urlAfterRedirects: "/landing", state: At}
main-es2015.4665a3d5fdcea262528d.js:1 Router Event: xe
main-es2015.4665a3d5fdcea262528d.js:1 ChildActivationStart(path: '')
main-es2015.4665a3d5fdcea262528d.js:1 xe {snapshot: Tt}
main-es2015.4665a3d5fdcea262528d.js:1 Router Event: Fe
main-es2015.4665a3d5fdcea262528d.js:1 ActivationStart(path: 'landing')
main-es2015.4665a3d5fdcea262528d.js:1 Fe {snapshot: Tt}
main-es2015.4665a3d5fdcea262528d.js:1 Router Event: 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 Router Event: Pe
main-es2015.4665a3d5fdcea262528d.js:1 ResolveStart(id: 7, url: '/', urlAfterRedirects: '/landing', state: Route(url:'', path:'') { Route(url:'landing', path:'landing') } )
main-es2015.4665a3d5fdcea262528d.js:1 Pe {id: 7, url: "/", urlAfterRedirects: "/landing", state: At}
main-es2015.4665a3d5fdcea262528d.js:1 Router Event: Te
main-es2015.4665a3d5fdcea262528d.js:1 ResolveEnd(id: 7, url: '/', urlAfterRedirects: '/landing', state: Route(url:'', path:'') { Route(url:'landing', path:'landing') } )
main-es2015.4665a3d5fdcea262528d.js:1 Te {id: 7, url: "/", urlAfterRedirects: "/landing", state: At}
main-es2015.4665a3d5fdcea262528d.js:1 Router Event: Me
main-es2015.4665a3d5fdcea262528d.js:1 ActivationEnd(path: 'landing')
main-es2015.4665a3d5fdcea262528d.js:1 Me {snapshot: Tt}
main-es2015.4665a3d5fdcea262528d.js:1 Router Event: Ne
main-es2015.4665a3d5fdcea262528d.js:1 ChildActivationEnd(path: '')
main-es2015.4665a3d5fdcea262528d.js:1 Ne {snapshot: Tt}
main-es2015.4665a3d5fdcea262528d.js:1 Router Event: be
main-es2015.4665a3d5fdcea262528d.js:1 NavigationEnd(id: 7, url: '/', urlAfterRedirects: '/landing')
main-es2015.4665a3d5fdcea262528d.js:1 be {id: 7, url: "/", urlAfterRedirects: "/landing"}
main-es2015.4665a3d5fdcea262528d.js:1 Router Event: Le
main-es2015.4665a3d5fdcea262528d.js:1 Scroll(anchor: 'null', position: 'null')
main-es2015.4665a3d5fdcea262528d.js:1 Le {routerEvent: be, position: null, anchor: null}

导航被取消两次。第一个原因是由于auth-guard在尝试获取“客户端”模块时返回false,但根据所记录的内容,似乎是另一个原因。

开发人员构建跟踪完全不同:

platform-browser.js:96 Router Event: NavigationStart
platform-browser.js:87 NavigationStart(id: 5, url: '/client')
platform-browser.js:87 NavigationStart {id: 5, url: "/client", navigationTrigger: "imperative", restoredState: null}
​ Router Event: RoutesRecognized
​ RoutesRecognized(id: 5, url: '/client', urlAfterRedirects: '/client', state: Route(url:'', path:'') { Route(url:'client', path:'client') { Route(url:'', path:'') }  } )
​ RoutesRecognized {id: 5, url: "/client", urlAfterRedirects: "/client", state: RouterStateSnapshot}
​ Router Event: GuardsCheckStart
​ GuardsCheckStart(id: 5, url: '/client', urlAfterRedirects: '/client', state: Route(url:'', path:'') { Route(url:'client', path:'client') { Route(url:'', path:'') }  } )
​ GuardsCheckStart {id: 5, url: "/client", urlAfterRedirects: "/client", state: RouterStateSnapshot}
​ Router Event: ChildActivationStart
​ ChildActivationStart(path: '')
​ ChildActivationStart {snapshot: ActivatedRouteSnapshot}
​ Router Event: ActivationStart
​ ActivationStart(path: 'client')
​ ActivationStart {snapshot: ActivatedRouteSnapshot}
​ Router Event: NavigationCancel
​ NavigationCancel(id: 5, url: '/client')
​ NavigationCancel {id: 5, url: "/client", reason: "Navigation ID 5 is not equal to the current navigation id 6"}
​ Router Event: NavigationStart
​ NavigationStart(id: 6, url: '/login?returnUrl=%2Fclient')
​ NavigationStart {id: 6, url: "/login?returnUrl=%2Fclient", navigationTrigger: "imperative", restoredState: null}
​ Router Event: RoutesRecognized
​ RoutesRecognized(id: 6, url: '/login?returnUrl=%2Fclient', urlAfterRedirects: '/login?returnUrl=%2Fclient', state: Route(url:'', path:'') { Route(url:'login', path:'login') } )
​ RoutesRecognized {id: 6, url: "/login?returnUrl=%2Fclient", urlAfterRedirects: "/login?returnUrl=%2Fclient", state: RouterStateSnapshot}
​ Router Event: GuardsCheckStart
​ GuardsCheckStart(id: 6, url: '/login?returnUrl=%2Fclient', urlAfterRedirects: '/login?returnUrl=%2Fclient', state: Route(url:'', path:'') { Route(url:'login', path:'login') } )
​ GuardsCheckStart {id: 6, url: "/login?returnUrl=%2Fclient", urlAfterRedirects: "/login?returnUrl=%2Fclient", state: RouterStateSnapshot}
​ Router Event: ChildActivationStart
platform-browser.js:87 ChildActivationStart(path: '')
platform-browser.js:87 ChildActivationStart {snapshot: ActivatedRouteSnapshot}
platform-browser.js:96 Router Event: ActivationStart
platform-browser.js:87 ActivationStart(path: 'login')
platform-browser.js:87 ActivationStart {snapshot: ActivatedRouteSnapshot}
platform-browser.js:96 Router Event: 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 Router Event: ResolveStart
platform-browser.js:87 ResolveStart(id: 6, url: '/login?returnUrl=%2Fclient', urlAfterRedirects: '/login?returnUrl=%2Fclient', state: Route(url:'', path:'') { Route(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 Router Event: ResolveEnd
platform-browser.js:87 ResolveEnd(id: 6, url: '/login?returnUrl=%2Fclient', urlAfterRedirects: '/login?returnUrl=%2Fclient', state: Route(url:'', path:'') { Route(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 Router Event: ActivationEnd
platform-browser.js:87 ActivationEnd(path: 'login')
platform-browser.js:87 ActivationEnd {snapshot: ActivatedRouteSnapshot}
platform-browser.js:96 Router Event: ChildActivationEnd
platform-browser.js:87 ChildActivationEnd(path: '')
platform-browser.js:87 ChildActivationEnd {snapshot: ActivatedRouteSnapshot}
platform-browser.js:96 Router Event: 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 Router Event: Scroll

感谢您的帮助。预先感谢。

1 个答案:

答案 0 :(得分:0)

如果您使用Firebase托管来托管您的构建,则需要启用对index.html的重写。

您可以通过添加rewrites部分在firebase.json文件中执行此操作:

{
  "hosting": {
    "public": "dist/browser",
    "rewrites": [
      {
        "source": "**",
        "destination": "/index.html"
      }
    ],
    ...
  }
}