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

#php #session #tabs

#php #сеанс #вкладки

Вопрос:

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

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

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

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

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

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

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

Ответ №1:

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

2. Вы можете отправить информацию по почте или ПОЛУЧИТЬ

Комментарии:

1. 21 марта 2023 года страница недоступна. Пожалуйста, используйте кэшированную версию Internet Archive: web.archive.org/web/20201010125653/https://sites.google.com /…

Ответ №2:

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

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

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

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

Ответ №3:

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

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

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

Ответ №4:

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

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

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

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

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