【问题标题】:How to detect if user open two tabs for same session?如何检测用户是否为同一会话打开两个选项卡?
【发布时间】:2011-07-31 07:19:15
【问题描述】:

我使用 CakePHP 完成了一个预订应用程序,其中涉及到结帐页面之前的几个步骤。在这些步骤之间,我将信息存储在会话中。

它的工作原理是第 1 步要求他们填写信息。进入第 2 步时,第 1 步中的信息将被保存到会话对象中。当他们继续进行其他步骤时,该过程会重复。最后结账时,所有数据都会保存到数据库中。

如果用户在浏览器中打开应用程序的一个实例,一切都会很好。但是,一旦他们在同一个浏览器中为同一个应用程序打开了另一个页面或另一个选项卡,就会出现问题。

假设他们在选项卡 A 和选项卡 B 中打开了两个应用程序实例。在选项卡 A 中,他们在步骤 1 中输入了详细信息并继续执行步骤 2。然后用户在选项卡 B 中执行相同的操作。

在用户结帐的最后一步,Tab A 中的信息与 Tab B 中的信息相同。

目前,我只能认为最好的方法是防止用户在两个浏览器实例中打开同一个应用程序。

当用户尝试在选项卡 B 中打开另一个实例时,是否有办法检测并提示用户先在选项卡 A 中填写预订表单?

【问题讨论】:

    标签: php session tabs


    【解决方案1】:

    当然,您可以使用客户端轮询脚本来实现这一点。在 JavaScript 中,您可以生成一个窗口 ID,只要它保证是唯一的就可以。让 JS 将 Ajax 调用者发送到服务器上的端点,该端点除了比较 ID 和会话之外什么都不做。在任何时候,如果您有两个不同的“windowID”值,您就知道它们必须为同一个会话打开窗口。

    您可以将其作为数组存储在服务器端,或者您甚至可以将其完全存储在客户端的 cookie 中。如果您选择这样做,您的客户端轮询器将只查看 cookie 值,如果它包含两个不同的值,则有问题。 Cookie 不太理想,因为它们增加了请求/响应周期的权重,并且您必须设置一种机制来在用户卸载页面时清除当前页面的值。

    对于服务器端实现,您只需发送当前的 windowID 以及链接或帖子,以便服务器可以从会话中清除 windowID。但是,这些都不能防止用户同时打开 Firefox 会话和 Chrome 会话。

    【讨论】:

      【解决方案2】:

      您可以在第 1 步首次启动时将会话标记为已启动。确保服务器端他们遵循正确的步骤(即在步骤 1 完成后他们不会返回到步骤 1,除非他们专门单击链接这样做。)基本上,跟踪他们在服务器上的当前步骤并更新它如所须。如果用户做了一些意想不到的事情,你可以让他们重新开始。

      我想知道表单上带有时间戳的隐藏字段是否有帮助。不过有点类似的想法。

      警告:此过程可能会破坏浏览器后退按钮的本质。我讨厌自己让这种情况发生在我的一个项目中。

      对于跨浏览器支持,您需要将其与用户帐户或持久存在的东西相关联。

      【讨论】:

        【解决方案3】:

        1.同样的问题(及解决方案):https://sites.google.com/site/sarittechworld/track-client-windows

        2.您可以通过POST或GET方式发送信息

        【讨论】:

          【解决方案4】:

          正如 Benjamin 指出的那样,您可以通过为每个窗口提供一个 ID 来做到这一点,然后您将每个请求都报告给服务器。如果要启用多窗口用例,我认为这是最合理的方法。

          我认为您不需要通过 ajax 轮询服务器来执行此操作。只要对服务器的每个请求都包含窗口 ID,您就可以消除服务器端与请求关联的会话的歧义。这意味着您的服务器端代码必须更改以将窗口 ID 作为会话的一部分。

          但是,这种方法有严重的缺陷。例如,如果用户同时关闭选项卡 A 和选项卡 B,然后打开一个新选项卡 C……会发生什么?他们应该重新连接哪组数据?

          如果您需要防止多个选项卡的状态混合,将用户限制在单个选项卡上的方法听起来很合理。

          顺便说一句,您可以通过本地存储来执行此操作。如果您在客户端生成一个随机 ID 并通过类似 window.localStorage.setItem('window_id', <my_random_id_here>); 的调用将其推送到本地存储中,那么您可以在页面加载时检查此值。如果在页面加载时该值存在,那么您将获得一个非常清晰的指示,表明至少有一个其他窗口处于打开状态。您必须确保在页面卸载时删除此值,否则死会话可能会触发误报。

          【讨论】:

            猜你喜欢
            • 2015-06-11
            • 1970-01-01
            • 2018-02-19
            • 2010-10-25
            • 1970-01-01
            • 2016-04-07
            • 2023-03-30
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多