【问题标题】:Unique session in multiple browser tabs in ASP.NET MVCASP.NET MVC 中多个浏览器选项卡中的唯一会话
【发布时间】:2014-04-02 15:44:47
【问题描述】:

每当用户在 ASP.NET MVC 应用程序中打开新的浏览器选项卡或窗口时,我都想创建唯一的会话。在 ASP.NET / MVC 中有可能吗?

我尝试遵循以下解决方案

asp.net - session - multiple browser tabs - different sessions?

但是它在 ASP.NET MVC 中不起作用。上面使用 ViewState 的解决方案,在 MVC 中我尝试使用 TempData 但它不起作用。

【问题讨论】:

  • 您尝试过 Session 吗?
  • 您的服务器无法知道用户何时在新选项卡中打开了页面。 (某些浏览器可能有这样的扩展,但 99.999% 的用户不会)。
  • 它不能与 Session 一起使用,因为会话值会被覆盖。

标签: asp.net asp.net-mvc


【解决方案1】:

多年后我终于找到了解决这个问题的方法:

1.) 浏览器必须自己提供 ID,因为 http 是无状态的,cookie 不是为浏览器选项卡单独存储的,因此 asp.net 会话也不区分单个选项卡。

2.) 打开新标签页时,JS window.name 为 ''。将 window.name 更改为某个值后,只要选项卡处于活动状态并且某些代码未更改它,它就不会再更改。

所以解决方法是:在 *.master 或每个 *.aspx 文件中实现一些简短的 JS 代码:

 if (typeof window.name != undefined) {
             if (window.name == '') {
                 var d = new Date();
                 window.name = '_myWnd_' + d.getUTCHours() + d.getUTCMinutes() + d.getUTCSeconds() + d.getUTCMilliseconds();
             }
             var eDiv = document.getElementById('div_BrowserWindowName');
             var e = eDiv.getElementsByTagName('input')[0];
             e.value = window.name;
         }

还可以在 *.master 或每个 *.aspx 文件的表单部分中添加:

 <div id="div_BrowserWindowName" style="visibility:hidden;">
                <asp:HiddenField ID="hf_BrowserWindowName" runat="server" />
            </div>

现在您可以通过在每次回发后读取隐藏字段来检索 window.name == UNIQUE ID,即使用户从一个站点跳转到另一个站点并在几个小时后返回表单。

【讨论】:

  • 我试图想象这种方法中的所有缺陷。您能否分享一下您是否仍然推荐这种技术?
  • 那么 MVC 呢??
【解决方案2】:

如您所知,HTTP 是无状态的,在请求之间建立状态的一种非常常见的机制是使用会话变量。当您打开一个新的浏览器选项卡时会出现问题,因为会话是相同的,因此您在新选项卡中所做的任何更改都会影响其他选项卡。 您没有具体说明您想要做什么,但假设您有一个产品列表页面,用户可以在其中输入搜索过滤器,并且您希望将它们保存在会话中。如果用户在选项卡 1 中设置搜索过滤器值,则选项卡 2 将具有相同的值(它们共享会话变量)。你能做什么?

1) 使用此方法在 URL 中添加 guid:http://www.codeproject.com/Articles/331609/Get-an-unique-session-in-each-browser-tab

2) 做一些类似于前一点描述的事情,但方式不同,这就是我为解决相同问题所做的事情。

a) 我到 serach 页面的链接是 /Product/List?guid=xxx 而不仅仅是 /Product/List。如果用户手动键入 /Product/List,我会将他重定向到设置了 GUID 的新 URL。

public ActionResult List(string guid)
        {
            if (guid == null)
            {
                return RedirectToAction("List", new { guid = Guid.NewGuid().ToString() });
            }
...

每次单击“列表”链接并定位新选项卡时,都会生成一个新的 GUID。

b) 我有一个带有 GUID 的会话密钥,因此每个页面都有自己的值。您可以同时打开 2 个选项卡,它们将使用不同的会话值,因为 guid 会有所不同。

这个解决方案并不完美,但至少它有效。

希望对你有帮助。

【讨论】:

    【解决方案3】:

    第一个答案的变体,使用 HTML 5,是使用 window.sessionStorage 而不是设置 window.name。所以你可以在你的应用程序的入口页面上做这样的事情:

    var uniqueId = "<%= Guid.NewGuid().ToString() %>";
    window.sessionStorage.setItem("tabId", uniqueId);
    

    然后在需要会话的每个控制器操作中,您通过以下方式传递参数:

    window.sessionStorage.getItem("tabId");
    

    【讨论】:

      猜你喜欢
      • 2011-02-19
      • 1970-01-01
      • 1970-01-01
      • 2014-09-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多