Я столкнулся с проблемой, в то время как я пересматривал свою библиотеку сеансов сегодня, и это может быть первый раз, когда я когда-либо видел проблему, специфичную для браузера, на сценарии конца. Надеюсь, кто-то может пролить свет.
В основном, как работает библиотека сеансов: при создании экземпляра он проверяет файл cookie с именем «id» (в виде результата uniqid) на клиентской машине. Если файл cookie найден, скрипт проверяет это и хешированную копию строки пользовательского агента на записи в таблице сеанса. Если соответствующая запись найдена, сценарий возобновляет сеанс. Если cookie с именем 'id' не найден или если в таблице сеансов не существует соответствующей записи, сценарий создает оба. Довольно стандартно, я думаю.
Теперь вот странная часть: в Firefox все работает так, как было предсказано. Пользователь получает один сеанс, который он всегда возобновляет при подключении, если не прошло и 24 часа бездействия. Но когда я посещаю страницу в Chrome, хотя она выглядит одинаково и, похоже, выполняет запросы в том же порядке, я вижу две записи в таблице сеансов. Сеансы разделяют строку агента, но идентификаторы различны, а журналы временной отметки указывают, что сеанс призрака создается в ближайшее время (через секунду) после созданного для пользователя.
Для целей отладки я печатал запросы на экран по мере их выполнения, и это пример того, что я вижу, когда Chrome должен открывать один сеанс и как-то открывать два:
// Attempting to resume a session SELECT id FROM sessions WHERE id = '4fd24a5cd8df12.62439982' AND agent = '9bcd5c6aac911f8bcd938a9563bc4eca' // No result, so it creates a new one INSERT INTO sessions (id, agent, start, last) VALUES ('4fd24ef0347f26.72354606', '9bcd5c6aac911f8bcd938a9563bc4eca', '1339182832', '1339182832') // Clear old sessions DELETE FROM sessions WHERE last < 1339096432
И вот что я вижу в базе данных позже:
id, agent, start, last 4fd24ef0347f26.72354606, 9bcd5c6aac911f8bcd938a9563bc4eca, 1339182832, 1339182832 4fd24ef0857f94.72251285, 9bcd5c6aac911f8bcd938a9563bc4eca, 1339182833, 1339182833
Мне что-то не хватает? Единственное, о чем я могу думать, это то, что Chrome может создавать скрытую сессию в фоновом режиме, возможно, для сканирования страницы. Если это так, это может стать проблемой позже, когда я начну связывать активные сеансы с записями в таблице users. Я искал возможные ошибки в моем скрипте, но пока ничего не нашел, и все работает как ожидается в Firefox.
Я столкнулся с этим раньше и был в равной степени озадачен. Начиная с нескольких месяцев назад Chrome имеет предварительную выборку. Таким образом, чтобы ускорить воспринимаемую скорость для пользователей, он просматривает большинство ссылок на странице и извлекает их и частично отображает их. Отлично подходит для конечных пользователей, поскольку, если вы используете широкополосный доступ, это может значительно сократить время смены страницы.
К сожалению для нас, веб-разработчиков, это приводит к путанице, как выше. Это происходит, например, когда пользователь Chrome посещает веб-сайт и ему еще не назначен куки-файл или сеанс, но браузер предварительно набрал несколько страниц и ему назначено несколько сеансов.
Итак, скажем, кто-то посещает страницу со ссылками на разные области вашего PHP-скрипта, а сценарий предназначен для назначения cookie всем посетителям … если Chrome выбирает два из этих страниц одновременно или близко к ним, PHP в конечном итоге назначит разные сеансы, потому что другой поток в Chrome будет в основном требовать нового сеанса / файла cookie до того, как будет выполнено другое задание.
Есть два решения, о которых я знаю: один из них – это API JavaScript для JavaScript, предназначенный для работы с prerendering , который я не нашел особенно хорошим. Другой способ – выполнить более строгую проверку при передаче сессий и файлов cookie с PHP. Либо не назначайте сеансы гостевым пользователям, либо добавляйте дополнительные проверки (IP, имя хоста, что угодно).
Надеюсь, это поможет.