PHP/Ajax "Vary: X-Requested-With" не работает для меня!
Я пытаюсь обслуживать кэшируемый контент в зависимости от того, является ли это запросом AJAX или нет.
Сценарий:
Небольшой PHP-скрипт "/test.php" обслуживает некоторый HTML-вывод и устанавливает следующие заголовки:
Expires Wed, 23 Feb 2011 13:30:06 GMT
Cache-Control public, max-age=60
Vary X-Requested-With,Accept-Encoding
Выход зависит от $_SERVER['HTTP_X_REQUESTED_WITH']
государство.
Когда мой Firefox указывает на URL-адрес, я получаю вывод, и в течение следующей минуты я получаю тот же результат из Browser-Cache, не затрагивая сервер. Хорошо пока
Когда я запрашиваю тот же ресурс через XMLHttpRequest
(с X-Requested-With: XMLHttpRequest
Заголовок), мой Firefox НЕ запрашивает сервер, но отправляет (неправильный) ответ из кэша!
С другой стороны, то же самое. Ajax-Call на ресурсе заполняет кэш, а последующий запрос браузера отправляет (неправильный) ответ от Cache.
У кого-нибудь есть опыт работы с этой темой? Я думаю, что это должно быть достаточно распространенной проблемой - подача контента в зависимости от того, является ли он ajax или нет (по тому же URL).
привет, Илья
1 ответ
Я могу воспроизвести это, но только если я не включу заголовок X-Requested-With в ответ ajax. Если я устанавливаю заголовок для вызова ajax, он работает в основном так, как ожидалось, хотя вызов ajax очищает кэш для обычного запроса и наоборот - контент не кэшируется, но вы никогда не получите неправильный контент.
Мой PHP документ выглядит так:
<?
putenv('TZ=PST8PDT');
date_default_timezone_set('America/Los_Angeles');
header('Expires: '.gmdate("D, d M Y H:i:s").' GMT');
header('Cache-Control: public, max-age=60');
header('Vary: X-Requested-With,Accept-Encoding');
echo 'it is now '.date('Y-m-d H:i:s');
?>
И моя тестовая страница такая:
<a href="resource.php" target="ifr">load into frame</a><br />
<iframe name="ifr" width="400" height="100"></iframe>
<hr />
<a href="#" onclick="return load();">load into div via ajax</a><br />
<div id="di" style="border: 1px solid black; width: 400px; height: 100px;"></div>
<script>
function load(){
var req = new XMLHttpRequest();
req.onreadystatechange = function(){
if (req.readyState == 4){
document.getElementById('di').textContent = req.responseText;
}
}
req.open('GET', 'resource.php', 1);
req.setRequestHeader("X-Requested-With", "XMLHttpRequest");
req.send(null);
return false;
}
</script>
Когда я нажимаю первую ссылку, она запрашивает с сервера. Когда я ударил его снова, он приходит из кеша. Каждый последующий клик приходит из кеша, до 60 секунд.
Когда я нажимаю вторую ссылку, запрос отправляется на сервер. Когда я ударил его снова, он приходит из кеша. Каждый последующий клик приходит из кеша, до 60 секунд.
Если я нажму ссылку 1, затем ссылку 2, они оба перейдут на сервер. Если я снова нажму ссылку 1, она снова отправится на сервер (что неправильно). Демо-последовательность (при условии, что все в течение 60 с):
Reg : server
Reg : cache
Reg : cache
Reg : cache
Ajax : server
Ajax : cache
Reg : server
Ajax : server
В результате, если вы хотите надежно кэшировать вещи по-разному при обслуживании через ajax, используйте другой URL при выполнении запроса ajax (? Ajax=1 будет работать нормально).
Я тестирую на FF 4.0 последней