2011-02-23 53 views
4

我正在尝试提供可缓存内容,具体取决于它是否是ajax请求。PHP/Ajax“Vary:X-Requested-With”不适用于我!

场景:

小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时,我得到输出,而对于下一个分钟,我从浏览器缓存中得到相同的结果,而不是击中服务器。好的,到目前为止。

当我通过XMLHttpRequest(与X-Requested-With: XMLHttpRequest标题)请求相同的资源时,我的Firefox不会请求服务器,但会提供Cache的(错误)响应!

对于其他方式,它是相同的。资源上的Ajax-Call会填充缓存,并且后续的浏览器请求会缓存来自缓存的(错误)响应。

有没有人有这方面的经验?我认为这应该是一个普遍的问题 - 根据是否使用ajax提供内容(在同一个URL上)。

问候,ILJA

+0

Firefox甚至不发送初始Ajax请求? – Gumbo 2011-04-16 19:38:00

回答

0

我可以重现这一点,但只有当我不包括X-要求,随着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服务,使用使得AJAX请求时不同的URL(AJAX = 1将做工精细)。

我在FF 4.0上测试最新

+0

x-requested-with对于在同一个URL上标识ajax请求是强制性的。我想根据RESTFUL接口在同一个URL上提供不同的内容。 – Ilja 2011-04-18 07:30:32

+0

答案是......你可以,但它不会正确缓存。演示代码是否按预期为您工作? – Cal 2011-04-18 08:22:51