我在您的代码中做了一些调试,我发现这不是因为链接、身份验证保护、导航声明或模块配置,也不是因为AG6 中的路由器蜂鸣,而是因为..... OAuth lib 你正在使用.
但让我解释一下。我发现正在发生以下情况:
- 您登录并被重定向回页面
- 您返回应用程序并使用 /#YOUR AUT TOKEN 之类的链接
- 已安排第一次导航(id 1)
- 导航导致重定向到子页面 /oversikt
- 导航2弹出(重定向)
- 路由器以异步方式执行所有操作——它们被序列化但仍然使用 RxJS 硬——所以实际处理被延迟——它已将当前导航 ID 作为参数传递(这很重要)
- 某些侦听器和其他订阅以及您正在使用的 OAUTH 库中的内容会触发
- 它(lib)检测到您的 url 中有令牌并删除它
- 这会触发另一个重定向 - 路由 id 立即递增到 3
- 现在导航 2 继续,在某个时候(记住 JS 是单线程的)它会检查(很好 id 做了很多)导航开头的导航 id 是否更改或仍然相同。
- 由于它有变化 - id 2 在计划时间传递,当前导航是 3,single
false
传播到整个管道和路由器中的订阅
- 将
boolean
(甚至不是假的,而是布尔值)作为管道中的值会导致无缘无故地取消导航。
生病添加一些代码参考。但总的来说,这就是正在发生的事情。您的 oauth 库在导航期间修改了 url 并导致它被取消。卫兵直接与此无关。
所以一般来说 - 它不会像警卫一样因为“访问被拒绝”而被取消,而是因为必须执行新的导航而被取消,所以它被取消短路。
这是(不是全部)相关代码:
OAuth 库修改
if (!this.oidc) {
this.eventsSubject.next(new OAuthSuccessEvent('token_received'));
if (this.clearHashAfterLogin && !options.preventClearHashAfterLogin) {
location.hash = '';
}
return Promise.resolve();
}
url 更改时触发导航:
Router.prototype.setUpLocationChangeListener = function () {
var _this = this;
// Don't need to use Zone.wrap any more, because zone.js
// already patch onPopState, so location change callback will
// run into ngZone
if (!this.locationSubscription) {
this.locationSubscription = this.location.subscribe(function (change) {
var rawUrlTree = _this.parseUrl(change['url']);
var source = change['type'] === 'popstate' ? 'popstate' : 'hashchange';
if(this.rou)
var state = change.state && change.state.navigationId ?
{ navigationId: change.state.navigationId } :
null;
setTimeout(function () { console.error("FROM LOCATION SUB");_this.scheduleNavigation(rawUrlTree, source, state, { replaceUrl: true }); }, 0);
});
}
};
导航 id 修改 - 立即发生:
var id = ++this.navigationId;
console.error("ANOTHER SCHEDULED LOL LOL LOL!!!");
this.navigations.next({ id: id, source: source, state: state, rawUrl: rawUrl, extras: extras, resolve: resolve, reject: reject, promise: promise });
// Make sure that the error is propagated even though `processNavigations` catch
// handler does not rethrow
return promise.catch(function (e) { return Promise.reject(e); });
这就是传递给路由器以启动“异步”路由的内容 - id 是导航 id(之前增加)
Router.prototype.runNavigate = function (url, rawUrl, skipLocationChange, replaceUrl, id, precreatedState) {
此检查(在 runNav 中)首先失败,因为 id 已更改,因此 2!==3 - FALSE 返回到管道
var preactivationCheckGuards$ = preactivationSetup$.pipe(mergeMap(function (p) {
if (typeof p === 'boolean' || _this.navigationId !== id) //NAVIGATION ID CHANGES HERE!
{
console.warn("PREACTIVATE GUARD CHECK ");
console.log(p);
// debugger;
return of(false);
}
chaing 中还有更多订阅,它们都有一些管道映射等以及已知的条件检查。
var preactivationResolveData$ = preactivationCheckGuards$.pipe(mergeMap(function (p) {
if (typeof p === 'boolean' || _this.navigationId !== id)
return of(false);
请注意,这就是我之前写的,如果你在这里得到任何布尔值,false 会被向前推。因为我们已经false
在这里,因为在以前的管道图中检查失败......
最后在链的末端
if (typeof p === 'boolean' || !p.shouldActivate || id !== _this.navigationId || !p.state) {
// debugger;
navigationIsSuccessful = false;
return;
}
结果标志设置为假,这会导致
.then(function () {
if (navigationIsSuccessful) {
_this.navigated = true;
_this.lastSuccessfulId = id;
_this.events
.next(new NavigationEnd(id, _this.serializeUrl(url), _this.serializeUrl(_this.currentUrlTree)));
resolvePromise(true);
}
else {
_this.resetUrlToCurrentUrlTree();
_this.events
.next(new NavigationCancel(id, _this.serializeUrl(url), ''));
resolvePromise(false);
}
NavigationCancel
没有您熟悉的任何消息(最后一个参数是消息 - 此处为空字符串):)。
因为我不知道有角的内部结构+那些该死的管道……到处都是管道,所以我花了更多的时间。
至于文档
NavigationCancel:取消导航时触发的事件。这是由于 Route Guard 在导航期间返回 false。
好吧,他们忘了提到内部路由器可以取消导航是否有导航队列建立:)
干杯!