Как определить, открывают ли пользователь две вкладки для одного сеанса?

Я сделал заявку на бронирование, выполненную с использованием CakePHP, которая включает несколько шагов перед страницей проверки. В промежутке между этими шагами я храню информацию в сеансе.

Как это работает, так это то, что шаг 1 требует, чтобы они заполнили свою информацию. При переходе к этапу 2 информация на шаге 1 будет сохранена в объект сеанса. Когда они выполняются на других этапах, процесс повторяется. В конце, когда они проверяют, все данные затем сохраняются в базе данных.

Все работает отлично, если пользователь открывает один экземпляр приложения в браузере. Но как только у них есть другая страница или другая вкладка, открытая для одного и того же приложения в том же браузере, проблема возникает.

Предположим, что у них есть два экземпляра приложения, открытых в Tab A и Tab B. В Tab A они ввели подробности на шаге 1 и перешли к шагу 2. Затем пользователь делает то же самое в Tab B.

На последнем шаге, когда пользователь делает проверку, информация в Tab A такая же, как в Tab B.

Прямо сейчас, я могу только думать, что лучший способ – запретить пользователю открывать одно и то же приложение в двух экземплярах браузера.

Есть ли способ обнаружить и пригласить пользователя заполнить форму бронирования в Tab A первым, когда они попытаются открыть другой экземпляр в Tab B?

Related of "Как определить, открывают ли пользователь две вкладки для одного сеанса?"

1.Такая же проблема (и решение): https://sites.google.com/site/sarittechworld/track-client-windows

2. Вы можете отправлять информацию по почте или GET

Вы можете отметить сеанс как начатый, когда первый шаг начинается. Убедитесь, что на стороне сервера они следуют за правильными шагами (т.е. они не возвращаются к шагу 1 после того, как шаг 1 был завершен, если они специально не нажимают ссылку для этого). В основном отслеживайте их текущий шаг на сервере и обновляйте его по мере необходимости. В случае, если пользователь делает что-то неожиданное, вы можете дать им возможность начать все заново.

Мне интересно, помогут ли скрытые поля с метками времени в ваших формах. Похоже, одна и та же идея.

Предостережение: этот процесс может нарушить суть кнопки вашего браузера. Я ненавижу себя за то, что позволил этому случиться в одном из моих проектов.

Для поддержки кросс-браузера вам необходимо связать его с учетной записью пользователя или чем-то, что сохраняется.

Конечно, вы можете добиться этого с помощью скрипта poller на стороне клиента. В JavaScript вы можете сгенерировать идентификатор окна, который может быть любым, если он будет уникальным. Попросите JS сделать абонентов Ajax конечной точке на сервере, которая ничего не делает, кроме сравнения идентификаторов и сеанса. В любом случае, если у вас есть два разных значения «windowID», вы знаете, что они должны иметь окна, открытые для одного сеанса.

Вы можете сохранить это на стороне сервера в виде массива в сеансе, или вы можете даже сохранить его полностью на стороне клиента в cookie. Если вы решили это сделать, ваш опросчик-клиент будет просто смотреть на значение cookie, и если он содержит два разных значения, что-то не так. Куки-файлы немного менее идеальны, хотя из-за того, что они добавляют вес к циклу запроса / ответа, и вам нужно будет настроить механизм, чтобы очистить значение текущей страницы, когда пользователь выгружает страницу.

Для серверной реализации вам просто нужно отправить текущий идентификатор окна вместе со ссылкой или сообщением, чтобы сервер мог очистить идентификатор окна от сеанса. Ничто из этого не защитило бы пользователя от сеанса Firefox и одновременного открытия сеанса Chrome.

Как отметил Бенджамин, вы можете сделать это, придумав идентификатор для каждого окна, который вы затем сообщаете на сервер с каждым запросом. Если вы хотите включить использование многократного использования окна, я думаю, что это наиболее разумный подход.

Я не думаю, что вам нужно опросить сервер через ajax, чтобы это сделать. Пока каждый запрос на сервер включает идентификатор окна, вы можете устранить, какой сеанс на стороне сервера должен связать запрос. Это будет означать, что ваш код на стороне сервера должен измениться, чтобы включить идентификатор окна как часть сеанса.

Однако этот подход имеет серьезные недостатки. Например, если пользователь закрывает как Tab A, так и Tab B, а затем открывает новую вкладку C … что происходит? С какими наборами данных они должны повторно соединяться?

Подход ограничения пользователя на одну вкладку звучит довольно разумно, если вам нужно предотвратить смешение нескольких состояний вкладок.

Вы можете сделать это через локальное хранилище, кстати. Если вы создаете случайный идентификатор на клиенте и вставляете его в локальное хранилище с помощью вызова типа window.localStorage.setItem('window_id', <my_random_id_here>); то вы можете проверить это значение при загрузке страницы. Если значение существует при загрузке страницы, у вас есть довольно четкий индикатор того, что открыто хотя бы одно другое окно. Вам нужно будет удалить это значение на странице unload, иначе мертвые сеансы могут вызывать ложные срабатывания.

Я думаю, что «запретить пользователю открывать один и тот же сеанс на двух вкладках» не лучшее решение.

У меня была аналогичная проблема.

Лучшее и прямое решение, которое я использовал, это формы Multi Step, см. Здесь . С помощью этого вы можете POST данные со всех шагов формы в вашу базу данных на этапе окончательной проверки. Вам не понадобятся переменные SESSION для переноса ваших данных с предыдущего шага на следующий шаг.

Это решает проблему с несколькими вкладками, и это дает вам возможность вернуться к предыдущему шагу формы.