当前位置:编程学习 > C#/ASP.NET >>

关于网页关闭的问题!急急急急急急急急急急急急

首先每个页面都有关闭功能,关闭又分关闭按钮、网页右上角的X关闭 、alt+F4、点击鼠标右键关闭      数据库里有个表有记录用户登录状态的字段,1为用户已登录,2为用户未登录,我在登陆页面登陆成功以后,把登陆状态2改为1,别人就无法再次登录了(提示用户已登录),如果点击退出按钮,正常退出的时候,可以把已登录状态修改成未登录状态,但是如果用户是用网页右上角的X关闭 、alt+F4、点击鼠标右键关闭的话,就无法修改登录状态了,用户下次登录的时候就会出现用户已登录的提示、我现在的Session存的用户信息,但是不登陆根本就获取不到Session   还有其中我们有个答题页面,只要没有点击提交按钮,无论用任何一种关闭方式,都会把此试卷插入到未完成的试卷表里!请各位高手帮忙看看啊!最好附详细代码与讲解,谢谢各位 --------------------编程问答-------------------- 你的这种方法实现单点登陆 很不现实 

用户退出的情况有止你想的这的这几种 还有系统强制重启,机器断电等等情况

你可以 换一种思路:

利用session.ID来实现后登陆的人将前边登陆的人T下线
--------------------编程问答-------------------- http://www.cnblogs.com/hl13571/archive/2008/01/28/1056671.html --------------------编程问答--------------------
引用 2 楼 q107770540 的回复:
http://www.cnblogs.com/hl13571/archive/2008/01/28/1056671.html


加菲猫。。哇哈哈 --------------------编程问答-------------------- http://home.cnblogs.com/group/topic/31823.html --------------------编程问答-------------------- http://www.cnblogs.com/igoogle/archive/2009/09/04/1560117.html --------------------编程问答-------------------- web程序中 貌似没有很好的方法去解决这个问题。

-----------------------

你可以用 application 去搞那个在线用户,配置系统定时查询用户状态。

那个未完成的 答卷。 你可以在用户选择 答卷的时候就插入一条 题目的ID,如果用户未提交,关联表中没有数据,则表示未完成。 --------------------编程问答-------------------- 请不要发链接,发链接人我是不会给分的! --------------------编程问答-------------------- 不太清楚,只说说自己的想法,用户的登录信息不是用session保存的吗,那么不管用户点击退出还是关闭浏览器,session就不是为null了么?也就是说只要保存用户信息的session为null就说明用户是未登录的,我也想不明白, --------------------编程问答-------------------- 接上,

    session["USER"]=session["user"];
    if(session["user"]==null)
       {
           就将session["USER"]保存的用户名的登录状态改为未登录;
             将session["USER"]改为null;
       }
    正常退出的话,只要将session["user"]改为null就可以了,
     --------------------编程问答-------------------- 监听session状态嘛...在session销毁的时候退出就是了,就是时效性差,还有在application启动的时候把所有已登陆的用户状态设置为未登陆就可以拉... --------------------编程问答-------------------- 补充:是在GOLBLE文件中定义的 --------------------编程问答-------------------- 我建议用JS脚本监控关闭事件,一下函数会监视到你的关闭事件,
然后在WebService()里面自己写调用数据库的代码。

//关闭前刷新List页面
function window.onbeforeunload() {
    if (event.clientX > 360 && event.clientY < 0 || (event.altKey)) {
        WebService(); //异步调用WebService改写数据库中的字段,这个函数需要自己写
    }
}
--------------------编程问答--------------------
引用 8 楼 csnd88 的回复:
不太清楚,只说说自己的想法,用户的登录信息不是用session保存的吗,那么不管用户点击退出还是关闭浏览器,session就不是为null了么?也就是说只要保存用户信息的session为null就说明用户是未登录的,我也想不明白,

同意楼上的  --------------------编程问答-------------------- QQ157636916详谈,你的问题很简单的。。 --------------------编程问答-------------------- 前不久我也遇到过
可以参考一下:

http://topic.csdn.net/u/20101019/10/63dfe9d0-1d2d-4cc9-8874-6e9f4eb30e22.html --------------------编程问答-------------------- 还是用ajax心跳保险。 --------------------编程问答-------------------- --------------------编程问答--------------------
引用 12 楼 jocxs 的回复:
我建议用JS脚本监控关闭事件,一下函数会监视到你的关闭事件,
然后在WebService()里面自己写调用数据库的代码。

JScript code

//关闭前刷新List页面
function window.onbeforeunload() {
    if (event.clientX > 360 && event.clientY < 0 || (event.a……

我的建议跟12楼类似用JS处理

 <script type="text/javascript">
            window.onbeforeunload = function() {
                return "请选择:";
            };
            window.onunload = function() {
                window.onbeforeunload = null;
                window.open("logout.aspx");
            }
        </script>

logout.aspx页面写用户的注销代码就行。 --------------------编程问答-------------------- 回贴拿分。。。 --------------------编程问答-------------------- 学习!!!!!!!! --------------------编程问答-------------------- 方法1
登录按钮中输入如下代码 

  private   void   Button1_Click(object   sender,   System.EventArgs   e) 
    { 
if(TextBox1.Text== "abc "   &   TextBox2.Text== "abc ")//和数据库验证通过,假设用户名密码均为 "abc " 
      { 
        //继续判断是否该用户已经登陆 
        Hashtable   h=(Hashtable)Application[ "Online "]; 

        if(h!=null) 
        { 
          //判断哈希表中是否有该用户 
          IDictionaryEnumerator   e1=h.GetEnumerator(); 
          bool   flag=false; 
          while(e1.MoveNext()) 
          { 
            if(e1.Value.ToString()== "abc ") 
            { 
              flag=true; 
              break; 
            } 
          } 
          if(flag)   //已经登陆 
          { 
            Label1.Text= "Login   already! "; 
            return; 
          } 
        } 
        else 
        { 
          h=new   Hashtable(); 
        } 

        //保存用户到Application中 
        h[Session.SessionID]= "abc "; 
        Application[ "Online "]=h; 
      } 
      else 
      { 
        TextBox1.Text= " "; 
        TextBox2.Text= " "; 
        Label1.Text= "User/Password   failed! "; 
        return; 
      } 
    } 

Global.asax文件中改写方法 

  protected   void   Session_End(Object   sender,   EventArgs   e) 
    { 
      Hashtable   h=(Hashtable)Application[ "Online "]; 
      
      if(h[Session.SessionID]!=null) 
        h.Remove(Session.SessionID); 

      Application[ "Online "]=h; 
    } 

方法2
由于某些原因,在我们的应用中会遇到一个用户只能在一个地方登录的情况,也就是我们通常所说的单点登录。在ASP.NET中实现单点登录其实很简单,下面就把主要的方法和全部代码进行分析。   

实现思路   

利用Cache的功能,我们把用户的登录信息保存在Cache中,并设置过期时间为Session失效的时间,因此,一旦Session失效,我们的Cache也过期;而Cache对所有的用户都可以访问,因此,用它保存用户信息比数据库来得方便。 
  
SingleLogin.aspx.cs代码   

usingSystem;   
usingSystem.Collections;   
usingSystem.ComponentModel;   
usingSystem.Data;   
usingSystem.Drawing;   
usingSystem.Web;   
usingSystem.Web.SessionState;   
usingSystem.Web.UI;   
usingSystem.Web.UI.WebControls;   
usingSystem.Web.UI.HtmlControls;   

namespaceeMeng.Exam   
{   
///   
///SingleLogin的摘要说明。   
///实现单点登录   
///   
publicclassSingleLogin:System.Web.UI.Page   
{   
protectedSystem.Web.UI.WebControls.TextBoxUserName;   
protectedSystem.Web.UI.WebControls.TextBoxPassWord;   
protectedSystem.Web.UI.WebControls.LabelMsg;   
protectedSystem.Web.UI.WebControls.ButtonLogin;   

privatevoidPage_Load(objectsender,System.EventArgse)   
{   
//实际例子可访问:   
//http://dotnet.aspx.cc/Exam/SingleLogin.aspx   
}   

#regionWeb窗体设计器生成的代码   
overrideprotectedvoidOnInit(EventArgse)   
{   
InitializeComponent();   
base.OnInit(e);   
}   

///   
///设计器支持所需的方法-不要使用代码编辑器修改   
///此方法的内容。   
///   
privatevoidInitializeComponent()   
{   
this.Login.Click+=newSystem.EventHandler(this.Login_Click);   
this.Load+=newSystem.EventHandler(this.Page_Load);   
}   
#endregion   

privatevoidLogin_Click(objectsender,System.EventArgse)   
{   
//作为唯一标识的Key,应该是唯一的,这可根据需要自己设定规则。   
//做为测试,这里用用户名和密码的组合来做标识;也不进行其它的错误检查。   

//生成Key   
stringsKey=UserName.Text+ "_ "+PassWord.Text;   
//得到Cache中的给定Key的值   
stringsUser=Convert.ToString(Cache[sKey]);   
//检查是否存在   
if(sUser==null||sUser==String.Empty)   
{   
//Cache中没有该Key的项目,表名用户没有登录,或者已经登录超时   
//注意下面使用的TimeSpan构造函数重载版本的方法,是进行是否登录判断的关键。   
TimeSpanSessTimeOut=newTimeSpan(0,0,System.Web.HttpContext.Current.Session.Timeout,0,0);   
HttpContext.Current.Cache.Insert(sKey,sKey,null,DateTime.MaxValue,SessTimeOut,   
System.Web.Caching.CacheItemPriority.NotRemovable,null);   
Session[ "User "]=sKey;   
//首次登录,您可以做您想做的工作了。   
Msg.Text= "嗨!欢迎您访问【孟宪会之精彩世界】 ";   
Msg.Text+= ",祝您浏览愉快!:) 
";   
}   
else   
{   
//在Cache中发现该用户的记录,表名已经登录过,禁止再次登录   
Msg.Text= "抱歉,您好像已经登录了呀:-( 
";   
return;   
}   
}   
}   
}   
摘自:http://topic.csdn.net/t/20051228/12/4486044.html --------------------编程问答-------------------- 最保险的是单用户在线模式,后来登陆挤掉先前登陆,不然的话,如果用户因为断电或死机或者浏览器崩溃而导致在线状态不能恢复,就只能等待SESSION过期了。 --------------------编程问答-------------------- 在web开发时,有的系统要求同一个用户在同一时间只能登录一次,也就是如果一个用户已经登录了,在退出之前如果再次登录的话需要报错

。 
  常见的处理方法是,在用户登录时,判断此用户是否已经在Application中存在,如果存在就报错,不存在的话就加到Application中

(Application是所有Session共有的,整个web应用程序唯一的一个对象):

以下是引用片段:

  string strUserId = txtUser.Text; 
  ArrayList list = Application.Get("GLOBAL_USER_LIST") as ArrayList; 
  if (list == null) 
  { 
  list = new ArrayList(); 
  } 
  for (int i = 0; i < list.Count; i++) 
  { 
  if (strUserId == (list[i] as string)) 
  { 
  //已经登录了,提示错误信息 
  lblError.Text = "此用户已经登录"; 
  return; 
  } 
  } 
  list.Add(strUserId); 
  Application.Add("GLOBAL_USER_LIST", list);
  当然这里使用Cache等保存也可以。

  接下来就是要在用户退出的时候将此用户从Application中去除,我们可以在Global.asax的Session_End事件中处理:

以下是引用片段:



  void Session_End(object sender, EventArgs e) 
  { 
  // 在会话结束时运行的代码。 
  // 注意: 只有在 Web.config 文件中的 sessionstate 模式设置为 
  // InProc 时,才会引发 Session_End 事件。如果会话模式设置为 StateServer 
  // 或 SQLServer,则不会引发该事件。 
  string strUserId = Session["SESSION_USER"] as string; 
  ArrayList list = Application.Get("GLOBAL_USER_LIST") as ArrayList; 
  if (strUserId != null && list != null) 
  { 
  list.Remove(strUserId); 
  Application.Add("GLOBAL_USER_LIST", list); 
  } 
  }
     这些都没有问题,有问题的就是当用户直接点浏览器右上角的关闭按钮时就有问题了。因为直接关闭的话,并不会立即触发Session过

期事件,也就是关闭浏览器后再来登录就登不进去了。

  这里有两种处理方式:

  1、使用Javascript方式

  在每一个页面中加入一段javascript代码:


以下是引用片段:

  function window.onbeforeunload() 
  { 
  if (event.clientX>document.body.clientWidth && event.clientY<0||event.altKey){ 
  window.open("logout.aspx"); 
  } 
  }
  由于onbeforeunload方法在浏览器关闭、刷新、页面调转等情况下都会被执行,所以需要判断是点击了关闭按钮或是按下Alt+F4时才执

行真正的关闭操作。

  然后在logout.aspx的Page_Load中写和Session_End相同的方法,同时在logout.aspx中加入事件:onload="javascript:window.close

()"

  但是这样还是有问题,javascript在不同的浏览器中可能有不同的行为,还有就是当通过文件->关闭时没有判断到。

  2、使用xmlhttp方法(这种方法测试下来没有问题)

  在每个页面中加入如下的javascript(这些javascript也可以写在共通里,每个页面引入就可以了)

以下是引用片段:

  var x=0; 
  function myRefresh() 
  { 
  var httpRequest = new ActiveXObject("microsoft.xmlhttp"); 
  httpRequest.open("GET", "test.aspx", false); 
  httpRequest.send(null); 
  x++; 
  if(x<60) //60次,也就是Session真正的过期时间是30分钟 
  { 
  setTimeout("myRefresh()",30*1000); //30秒 
  } 
  } 
  myRefresh();

  在web.config中设置:<sessionState mode="InProc" timeout="1"></sessionState> 

  test.aspx页面就是一个空页面,只不过需要在Page_Load中加入:Response.Expires = -1;

  保证不使用缓存,每次都能调用到这个页面。

  原理就是:设置Session的过期时间是一分钟,然后在每个页面上定时每30秒连接一次测试页面,保持Session有效,总共连60次,也就

是30分钟。如果30分钟后用户还没有操作,Session就会过期。当然,如果用户直接关闭浏览器,那么一分钟后Session也会过期。这样就可

以满足要求了。
--------------------编程问答--------------------
补充:.NET技术 ,  ASP.NET
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,