Почему совместное использование сеансов PHP между одновременно открытыми страницами работает в FF, а не в IE или Chrome? - PullRequest
3 голосов
/ 07 октября 2009

РЕДАКТИРОВАТЬ Я только что понял, что у меня, должно быть, был огромный пердеть при написании сокращенного примера кода. Видишь, я пользуюсь умом. Таким образом, я на самом деле уже использую решение Кипса, потому что Smarty отображается после сохранения сеанса

Я работал над реализацией менеджера ресурсов (для сжатия, сжатия и минимизации CSS и JS) для сайта PHP, над которым я работаю, и столкнулся с очень странной проблемой. Поэтому, когда пользователь переходит к index.php, файлы добавляются в объект диспетчера ресурсов, который объединяет их в один файл и включается в страницу с помощью <script src="resource.php?id=123&ext=.js"> или <link href="resource.php?id=123&ext=.css" />

.

То, что в основном сводится к тому, что путь к файлу сохраняется в сеансе на странице, к которой осуществляется доступ, и читается из сеанса на странице ресурса. В FF это работает отлично. В IE и Chrome это не так.

Вот очень сокращенный пример кода:

index.php

<?php
session_start();
//Do a ton of stuff
//Including adding several files to the resource object
//Add the resource links to the head
$smarty->append('headSection','<link href="resource.php?id=<?=$resourceID?>&type=.js" />');
</head>
//Save the resource file which:
// - Outputs the file
// - Saves a reference to it in session
$_SESSION[$resourceID] = $file;
//Let Smarty display
$smarty->display($templateFile);
?>

resource.php

<?php
readfile($_SESSION[$_GET['id']] . $_GET['type']);
?>

Мне кажется, что FF ждет ответа всей страницы, прежде чем делать какие-либо новые запросы к ресурсам, требуемым для страницы, в то время как IE и Chrome работают, начиная новый запрос, как только он встречается. Из-за этого эта ошибка в основном сводится к состоянию гонки.

Кто-нибудь может подтвердить, что это действительно так? И если так - как бы я обойти это?

Ответы [ 2 ]

1 голос
/ 07 октября 2009

Редактировать : После обновления вашего вопроса я не удивлюсь, что вы получаете состояние гонки. Я не знаю, почему он работает в Firefox, но IE и Chrome определенно не делают ничего противозаконного, запрашивая ресурсы заранее. Один из способов решить эту проблему - с помощью буферизации вывода. В верхней части вашего файла index.php вы можете добавить:

ob_start('ob_gzhandler');

Это убивает двух зайцев одним выстрелом: а) следя за тем, чтобы вывод был буферизован, чтобы браузер не видел файл, пока не будет сгенерирована вся страница; и б) сохранение пропускной способности вас и ваших пользователей с помощью сжатия gzip.


Предыдущий ответ : Кажется, это не имеет смысла. Файлы cookie могут быть установлены только в заголовке, что происходит перед загрузкой любого содержимого страницы. Таким образом, браузер запрашивает index.php, и в заголовке устанавливается cookie PHPSESSID. Затем содержимое страницы доставляется.

В данный момент у меня нет доступа к машине с PHP, но следующее может помочь проверить вашу теорию. test1.php устанавливает переменную сеанса, но затем для полного завершения загрузки требуется 30 секунд. Тем временем test2.php (файл CSS) попытается использовать эту переменную сеанса в качестве цвета текста. Текст будет отображаться красным, если сеанс может быть прочитан из test2, или черным (цвет по умолчанию) в противном случае.

test1.php

<?php
session_start();
$_SESSION['mycolor'] = 'red';
?>
<html>
<head>
<link rel="stylesheet" href="test2.php" type="text/css" />
</head>
<body>
Starting test...<br/>
<?php
for($i = 0; $i < 6; $i++) //loop will take 30 seconds to complete
{
  echo "$i<br/>\n";
  sleep(5);
}
?>
Done!
</body>
</html>

test2.php

<?php
session_start();
?>
body { color: <?php echo $_SESSION['mycolor']; ?>; }
0 голосов
/ 08 октября 2009

Я наконец понял, что нужно было исправить. Для начала, предложенное Кипом решение является правильным, однако на самом деле это не было решением моей проблемы, поскольку то, что я сказал, было то, что моя проблема на самом деле не была моей проблемой ... более или менее.

В одном из тестов, которые я проводил, я внезапно заметил, что SessionID был различным для страницы и для файла ресурсов. Я понятия не имел, как это возможно, пока не вспомнил, что в другом компоненте, который я включаю в страницу, я регенерирую SessionID (session_regenerate_id()), чтобы предотвратить атаки CSRF. Как только я прокомментировал эту строку, все работало отлично в каждом браузере.

Однако для меня это поднимает новый вопрос ... Почему session_regenerate_id () не сохраняет данные сеанса?

Редактировать - Продолжать: Кажется, что это на самом деле известная проблема, и она хорошо документирована в комментариях на странице документации PHP для session_regenerate_id ().

Начните здесь: http://www.php.net/manual/en/function.session-regenerate-id.php#81212 и прочитайте.

...