如何显示足够智能的会话超时警告来处理多个打开的浏览器或选项卡

发布于 2024-07-10 10:09:35 字数 163 浏览 10 评论 0原文

我已经使用 JavaScript 实现了会话超时警告,它只是询问用户是否要延长会话或注销。 问题在于,这是针对 Intranet 门户的,高级用户通常会同时打开多个浏览器窗口或选项卡来访问应用程序。 目前,系统会提示他们即将从每个浏览器窗口注销。 如何使代码更智能地检测到他们正在主动使用另一个浏览器会话?

I have implemented a session timeout warning using javascript that simply asks the user if they want to extend their session or logout. The problem is that this is for an intranet portal where power users will often have several browser windows or tabs open at the same time to the application. Currently, they will be prompted that they are about to be logged out from every browser window. How can I make the code smarter to detect that they are actively using another browser session?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

吹泡泡o 2024-07-17 10:09:35

您必须使用 Ajax 检查服务器上的会话状态并跟踪用户拥有的所有打开的会话/窗口。 然后,您就可以仅针对可用会话之一发出注销警告。

回应您的评论:

不要使用内置会话机制,使用服务器端持久数组或数据库日志设计您自己的机制。

不,HTTP 请求中没有任何内容告诉您打开了多少个浏览器,但您可以在用户打开每个浏览器窗口时分配自己的 sessionID cookie。 对服务器进行 Ajax 调用,查看用户是否超时,如果您是会话日志中的最低(或最后)条目,那么您就是收到警告的浏览器。

You'd have to check the session state on the server using Ajax and keep track of all the open sessions/windows the user has. You'd then be able to target only one of the available sessions with the log out warning.

In response to your comment:

Don't use the built-in session mechanism, devise your own using an server-side presistent array or a database log.

No, nothing in the HTTP request tells you how many browsers are open, but you can assign your own sessionID cookie as the user opens each browser window. Make an Ajax call to the server, see if the user has timed-out, and if you're the lowest (or last) entry in the session log then you're the browser that gets the warning.

合约呢 2024-07-17 10:09:35

您不能指望所有选项卡/窗口都属于同一会话,因为它们可能会生成并包含在单独的进程中,而您对此没有太多控制权。

但是,如果您的代码引用 Javascript cookie,您可以通过回发(同步或异步 AJAX)检查伪会话状态。 但随后您就依赖于用户浏览器上启用的 cookie。

You can't count on all tabs/windows to be part of the same Session, because they could be spawned and contained within separate processes and you don't have much control over that.

But if your code references a Javascript cookie, you can check your pseudo-session state via a postback (synchronous or asynchronous AJAX). But then you're depending on cookies being enabled on the user's browser.

薆情海 2024-07-17 10:09:35

这行得通吗?

存储 Javascript cookie 并检查以确定会话是否已在另一个选项卡中扩展?

看起来这确实有效...

Would this work?

Store a Javascript cookie and check that to determine if the session has been extended in another tab?

looks like this does work...

我是有多爱你 2024-07-17 10:09:35

安装@ng-idle
@ng-idle 可通过 NPM 获得。 通过运行安装它:

npm install --save @ng-idle/core @ng-idle/keepalive angular2-moment

设​​置您的应用程序模块
使用 then 导入 Ng2IdleModule

import { 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 { }

打开 src/app/app.module.ts 并在 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;
    }
}

Install @ng-idle
@ng-idle is available via NPM. Install it by running:

npm install --save @ng-idle/core @ng-idle/keepalive angular2-moment

Set up your application module
Open src/app/app.module.ts and import the Ng2IdleModule using

import { 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 { }

then in 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;
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文