在ASP.NET中处理会话超时的最佳方法是什么?

6

处理会话超时有多种方法,例如“meta刷新”、在加载函数上使用javascript等。

我想要一个简洁的东西:在超时前5分钟,警告用户......

我还在考虑只要浏览器打开,就保持会话处于打开状态(不过还需要弄清楚如何做...可能是一些带有刷新功能的iframe)。

你是如何处理会话超时的,你认为我应该采取什么方向?

3个回答

3
处理会话超时的最佳方法。
我认为有两种基本情况。一种是用户输入很少或没有数据,只是阅读报告或使用鼠标进行小操作。在这种情况下,很难通知用户会话即将过期。如果您要调用后台代码检查会话剩余时间,那么会自动更新会话。然后,如果您有一个计时器来倒计时会话时间,那么可能用户已经打开了您网站的新选项卡,并且会话即将过期,但是您通过JavaScript记录的时间不正确,用户会收到错误的消息。
因此,对于我来说,当用户输入很少或没有数据时,就让会话过期,如果他失去了一个点击,稍后会再次尝试。
第二种情况是当用户需要输入大量数据时,这可能需要一些时间,例如长文本,需要编写和修复。在这种情况下,我使用以下技术,并且不让会话结束。
如何保持会话与浏览器同步。
这里有一种非常好的简单技术,我使用一张图片,在会话超时之前使用JavaScript重新加载它。
<img id="keepAliveIMG" width="1" height="1" src="/img/ui/spacer.gif?" /> 

<script language="javascript" type="text/javascript"> 
    var myImg = document.getElementById("keepAliveIMG");

    if (myImg){
        window.setInterval(function(){
              myImg.src = myImg.src.replace(/\?.*$/, '?' + Math.random());
            }, 6000);
    }   
</script> 

在第三种情况下,您可以这样做。我们只在回传时关注会话是否过期。当用户输入一些数据并在回传时应用程序将其重定向到登录页面并且帖子丢失时,我们需要处理。
在这种第三种情况下,您可以捕获帖子数据并保存它们,直到用户重新登录。您可以在global.asax上捕获帖子数据。
protected void Application_AuthenticateRequest(Object sender, EventArgs e)

这是在重定向到登录页面之前调用的函数,在这里您可以查看是否有发布数据和使用登录所需的信息,然后将该发布数据保存到新的重定向页面或服务器上(可能在会话上,也可能在临时数据库上)。
现在,用户再次登录后,您将其重新重定向到具有保存的发布数据的上一页,并使用户继续操作。
唯一的技巧是创建一个中间页面,该页面使用最后提交的数据呈现表单和自动重定向javascript调用。

我喜欢这种方法,但你必须确保图像缓存未设置,并且文件夹安全性不仅在配置中设置为匿名。一个缺点是,如果会话确实过期了,除非设置一个onerror事件,否则页面无法警告用户。 - Codesleuth
@Codesleuth 如果你仔细看代码,你会发现我在图片末尾生成了一个随机数 - 这样就不会被缓存。这段代码已经经过了与其他4种方法的测试,并且目前正在运行并且有效 :) - Aristos
是的,这似乎是保持会话开放的一个不错的方法。比起我最初想到的iframe要好得多。 - stoic
啊,原来是这样:) 做得很好。个人认为我会坚持使用自己的keepalive ajax调用,因为我可以返回相关信息以获取状态更新(系统警报:D) - Codesleuth

1
我能想到的唯一方法就是在页面上生成一些脚本,创建一个客户端计时器,这样当页面被接收和渲染后,它可以在 X 分钟后(即过期前 5 分钟)显示警报。
如果您希望会话保持活动状态,您可以使用通用处理程序(ASHX),通过 AJAX 定期调用它来实现。这将有助于刷新会话,并且只要 AJAX 调用继续,会话就应该保持活动状态。
示例 "keepalive.ASHX":
<%@ WebHandler Language="C#" Class="keepalive" %>

using System;

public class keepalive : System.Web.IHttpHandler
{       
    public void ProcessRequest (System.Web.HttpContext context) 
    {
        context.Response.ContentType = "text/json";
        var thisUser = System.Web.Security.Membership.GetUser();

        if (thisUser != null)
            context.Response.Write("[{\"User\": \"" + thisUser.UserName + "\"}]");
    }

    public bool IsReusable
    {
        get { return false; }
    }
}

这里是页面上调用它的脚本(为了简单起见,使用jQuery):

<script type='text/javascript'>
    function keepAliveInterval()
    {
        $.ajax(
        {
            url: "keepalive.ashx",
            context: document.body,
            error: function () {
                alert("AJAX keepalive.ashx error :(");
            }
        });
    }

    $(document).ready(function () {
        window.setInterval('keepAliveInterval()', 60000);
    });
</script>

从您调用keepalive.ashx的那一刻起,用户的会话是否更新? - Aristos
我不确定处理程序是如何工作的,但这个方法如何保持会话开放?创建一个 Web 服务并通过 JavaScript 每5分钟调用一个函数是否可以达到相同效果?如果可以...那么有什么缺点? - stoic
@Aristos:是的,但如果它因为其他原因过期,错误警报将告诉用户(即他们是否在另一个选项卡/窗口中注销?) - Codesleuth
1
你的代码也是个好主意,对于提供更多有用的信息也是有帮助的。 - Aristos

0

使用一些 jQuery,依赖于 web.config 中的会话超时变量。您可以使用 this Jquery 延迟技巧,在特定时间(页面加载后 x 分钟)发生时,弹出一个 div,显示会话在 x 分钟后超时。非常好看、干净和简单。

关于会话超时,Codesleuth 的 ajax 调用是完美的。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接