Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/amazon-s3/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 如何检测用户是否为同一会话打开了两个选项卡?_Php_Session_Tabs - Fatal编程技术网

Php 如何检测用户是否为同一会话打开了两个选项卡?

Php 如何检测用户是否为同一会话打开了两个选项卡?,php,session,tabs,Php,Session,Tabs,我已经使用CakePHP完成了一个预订应用程序,它涉及到结账页面之前的几个步骤。在这些步骤之间,我将信息存储在会话中 其工作原理是,第1步要求他们填写信息。转到步骤2时,步骤1中的信息将保存到会话对象中。当他们在其他步骤中继续时,该过程会重复。最后,当他们签出时,所有数据都保存到数据库中 如果用户在浏览器中打开应用程序的一个实例,一切都会很好。但一旦他们在同一浏览器中为同一应用程序打开了另一个页面或另一个选项卡,问题就发生了 假设他们在选项卡A和选项卡B中打开了应用程序的两个实例。在选项卡A中,

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

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

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

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

在用户进行签出的最后一步,选项卡a中的信息与选项卡B中的信息相同

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


当用户尝试在选项卡B中打开另一个实例时,是否有方法检测并提示用户首先在选项卡a中完成预订表单?

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

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


对于服务器端实现,您只需要将当前的windowID与link或post一起发送,以便服务器可以从会话中清除windowID。但是,所有这些都不能防止用户同时打开Firefox会话和Chrome会话。

您可以在第一步启动时将会话标记为已启动。确保服务器端用户遵循正确的步骤(即,在完成步骤1后,除非他们专门单击链接,否则不会返回到步骤1)。基本上,在服务器上跟踪他们当前的步骤,并根据需要进行更新。如果用户做了一些意外的事情,您可以给他们重新开始的选项

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

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

对于跨浏览器支持,您需要将其与用户帐户或持续存在的内容关联。

1.同样的问题(和解决方案):


2.您可以通过POST或GET发送信息,正如Benjamin指出的,您可以通过提供每个窗口的ID来完成,然后在每次请求时向服务器报告。如果您想启用多窗口用例,我认为这是最合理的方法

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

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

如果需要防止多个状态选项卡的混合,那么将用户限制为单个选项卡的方法听起来相当合理

顺便说一句,您可以通过本地存储实现这一点。如果您在客户端上生成一个随机ID,并通过调用
window.localStorage.setItem('window_ID',)将其推入本地存储中然后可以在页面加载时检查此值。如果该值在页面加载时存在,则会有一个非常清楚的指示器,指示至少有一个窗口处于打开状态。您必须确保在页面卸载时删除此值,否则死机会话可能会触发误报