我已经使用javascript实现了会话超时警告,该警告只是询问用户是否要扩展其会话或注销。问题在于,这适用于内部网门户,其中高级用户通常会同时打开多个浏览器窗口或选项卡到应用程序。目前,系统会提示他们即将从每个浏览器窗口注销。如何使代码更智能,以检测他们是否正在使用其他浏览器会话?
答案 0 :(得分:2)
您必须使用Ajax检查服务器上的会话状态,并跟踪用户拥有的所有打开的会话/窗口。然后,您只能使用注销警告来定位其中一个可用会话。
回应你的评论:
不要使用内置会话机制,使用服务器端presistent数组或数据库日志设计自己的。
不,HTTP请求中没有任何内容告诉您打开了多少浏览器,但是当用户打开每个浏览器窗口时,您可以分配自己的sessionID cookie。对服务器进行Ajax调用,查看用户是否已超时,如果您是会话日志中的最低(或最后)条目,那么您就是获得警告的浏览器。
答案 1 :(得分:2)
您不能指望所有选项卡/窗口都属于同一个会话,因为它们可能会生成并包含在单独的进程中,您无法对其进行太多控制。
但是如果您的代码引用了Javascript cookie,您可以通过回发(同步或异步AJAX)检查您的伪会话状态。但是,你依赖于在用户浏览器上启用的cookie。
答案 2 :(得分:0)
这会有用吗?
存储Javascript cookie并检查以确定会话是否已在另一个选项卡中扩展?
看起来这确实有用......
答案 3 :(得分:0)
安装@ ng-idle @ ng-idle可通过NPM获得。通过运行安装它:
npm install --save @ng-idle/core @ng-idle/keepalive angular2-moment
设置您的应用程序模块 打开src / app / app.module.ts并使用
导入Ng2IdleModuleimport { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { HttpModule } from '@angular/http';
import { NgIdleKeepaliveModule } from '@ng-idle/keepalive'; // this includes the core NgIdleModule but includes keepalive providers for easy wireup
import { MomentModule } from 'angular2-moment'; // optional, provides moment-style pipes for date formatting
import { AppComponent } from './app.component';
@NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule,
FormsModule,
HttpModule,
MomentModule,
NgIdleKeepaliveModule.forRoot()
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
然后在component.ts中
import { Component } from '@angular/core';
import {Idle, DEFAULT_INTERRUPTSOURCES} from '@ng-idle/core';
import {Keepalive} from '@ng-idle/keepalive';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
currentPath: String;
idleState = 'Not started.';
timedOut = false;
lastPing?: Date = null;
constructor(private idle: Idle, private keepalive: Keepalive, location: Location, router: Router) {
// sets an idle timeout of 5 seconds, for testing purposes.
idle.setIdle(5);
// sets a timeout period of 5 seconds. after 10 seconds of inactivity, the user will be considered timed out.
idle.setTimeout(5);
// sets the default interrupts, in this case, things like clicks, scrolls, touches to the document
idle.setInterrupts(DEFAULT_INTERRUPTSOURCES);
idle.onIdleEnd.subscribe(() => this.idleState = 'No longer idle.');
idle.onTimeout.subscribe(() => {
this.idleState = 'Timed out!';
this.timedOut = true;
});
idle.onIdleStart.subscribe(() => this.idleState = 'You\'ve gone idle!');
idle.onTimeoutWarning.subscribe((countdown) => this.idleState = 'You will time out in ' + countdown + ' seconds!');
// Sets the ping interval to 15 seconds
keepalive.interval(15);
keepalive.onPing.subscribe(() => this.lastPing = new Date());
// Lets check the path everytime the route changes, stop or start the idle check as appropriate.
router.events.subscribe((val) => {
this.currentPath = location.path();
if(this.currentPath.search(/authentication\/login/gi) == -1)
idle.watch();
else
idle.stop();
});
}
reset() {
this.idle.watch();
this.idleState = 'Started.';
this.timedOut = false;
}
}