防止浏览器缓存jQuery AJAX调用结果

时间:2008-12-15 08:44:11

标签: javascript jquery ajax browser-cache

如果我使用$.get()加载动态内容,结果会缓存在浏览器中。

在QueryString中添加一些随机字符串似乎可以解决这个问题(我使用new Date().toString()),但这感觉就像一个黑客。

还有其他方法可以达到这个目的吗? 或者,如果唯一字符串是实现此目的的唯一方法,那么除了new Date()之外的任何建议?

19 个答案:

答案 0 :(得分:501)

以下将阻止所有未来的AJAX请求被缓存,无论您使用哪种jQuery方法($ .get,$ .ajax等)

$.ajaxSetup({ cache: false });

答案 1 :(得分:295)

JQuery的$ .get()将缓存结果。而不是

$.get("myurl", myCallback)

你应该使用$ .ajax,这将允许你关闭缓存:

$.ajax({url: "myurl", success: myCallback, cache: false});

答案 2 :(得分:225)

我使用new Date().getTime(),这将避免冲突,除非您在同一毫秒内发生多个请求:

$.get('/getdata?_=' + new Date().getTime(), function(data) {
    console.log(data); 
});

编辑:这个答案已经有好几年了。它仍然有效(因此我没有删除它),但是现在有更好/更清晰的方法来实现这个目标。我的偏好是this方法,但如果您想在页面生命周期内禁用每个请求的缓存,那么this答案也很有用。

答案 3 :(得分:23)

另一种方法是在生成对ajax调用的响应的代码中不从服务器端提供缓存头:

response.setHeader( "Pragma", "no-cache" );
response.setHeader( "Cache-Control", "no-cache" );
response.setDateHeader( "Expires", 0 );

答案 4 :(得分:18)

此处的所有答案都会在请求的URL上留下足迹,该URL将显示在服务器的访问日志中。

我需要一个没有副作用的基于标头的解决方案,我发现可以通过设置How to control web page caching, across all browsers?中提到的标题来实现。

至少为Ch​​rome工作的结果将是



$.ajax({
   url: url, 
   headers: {
     'Cache-Control': 'no-cache, no-store, must-revalidate', 
     'Pragma': 'no-cache', 
     'Expires': '0'
   }
});




答案 5 :(得分:13)

我个人觉得查询字符串方法比尝试在服务器上设置标头更可靠 - 不能保证代理或浏览器不会只是缓存它(某些浏览器比其他浏览器更糟糕 - 没有命名)

我通常使用Math.random()但是我没有看到使用日期有什么问题(你不应该足够快地执行AJAX请求以获得相同的值两次)。

答案 6 :(得分:5)

真正的问题是为什么你需要这个不被缓存。如果它不应该被缓存,因为它一直在变化,服务器应该指定不缓存资源。如果它有时只是改变(因为它所依赖的资源之一可以改变),并且如果客户端代码有办法知道它,它可以将一个伪参数附加到从某个散列或最后修改日期计算的url这些资源(这就是我们在Microsoft Ajax脚本资源中所做的事情,因此它们可以永久缓存,但新版本仍然可以在它们出现时提供)。如果客户端无法知道更改,那么正确的方法应该是服务器正确处理HEAD请求并告诉客户端是否使用缓存版本。 对我来说似乎是附加一个随机参数或从客户端告诉从不缓存是错误的,因为可缓存性是服务器资源的属性,因此应该在服务器端决定。 问自己的另一个问题是,这个资源是真的应该通过GET服务还是应该通过POST?这是一个语义问题,但它也有安全隐患(有些攻击仅在服务器允许GET时才有效)。 POST不会被缓存。

答案 7 :(得分:5)

如何使用POST请求代替GET ......? (无论如何你应该......)

答案 8 :(得分:4)

当然,“缓存破解”技术将完成工作,但如果服务器向客户端指示不应缓存响应,则不会首先发生这种情况。在某些情况下,缓存响应是有益的,有时则不是。让服务器决定数据的正确生命周期。您可能希望稍后更改它。从服务器上比在UI代码中的许多不同位置更容易做到。

当然,如果您无法控制服务器,这无济于事。

答案 9 :(得分:4)

也许你应该看看$ .ajax()(如果你使用的是jQuery,它看起来像)。 请查看:http://docs.jquery.com/Ajax/jQuery.ajax#options和“缓存”选项。

另一种方法是查看如何在服务器端缓存内容。

答案 10 :(得分:3)

给出的优秀答案的一小部分补充:如果您正在为没有javascript的用户运行非ajax备份解决方案,则无论如何都必须使这些服务器端标头正确。这并非不可能,虽然我理解那些放弃它的人;)

我确信在SO上还有另一个问题,它会为您提供适当的完整标题集。我并非完全信任的老鼠回复涵盖所有基地100%。

答案 11 :(得分:3)

对于那些在移动版Safari上使用cache $.ajaxSetup()选项的人来说,似乎您可能必须使用POST的时间戳,因为移动版Safari也会缓存它。根据{{​​1}}上的文档(您从$.ajax()转发):

  

将缓存设置为false只能在HEAD和GET请求中正常工作。它的工作原理是附加" _ = {timestamp}"到GET参数。其他类型的请求不需要该参数,但在IE8中,当对已经由GET请求的URL进行POST时,该参数除外。

因此,在我上面提到的情况下,单独设置该选项无法帮助您。

答案 12 :(得分:2)

基本上只需在ajax中添加cache:false;,您认为内容会随着进度的变化而变化。内容不会改变的地方你可以省略这个。这样,你每次都会得到新的回复

答案 13 :(得分:2)

Internet Explorer’s Ajax Caching: What Are YOU Going To Do About It?提出了三种方法:

  
      
  1. 将缓存清除令牌添加到查询字符串,例如?date = [timestamp]。在jQuery和YUI中,您可以告诉他们自动执行此操作。
  2.   
  3. 使用POST代替GET
  4.   
  5. 发送专门禁止浏览器缓存它的HTTP响应标头
  6.   

答案 14 :(得分:1)

如果您使用的是IE 9,则需要在控制器类定义之前使用以下内容:

[OutputCache(NoStore = true,Duration = 0,VaryByParam =“*”)]

public class TestController:Controller

这会阻止浏览器缓存。

此链接的详细信息: http://dougwilsonsa.wordpress.com/2011/04/29/disabling-ie9-ajax-response-caching-asp-net-mvc-3-jquery/

实际上这解决了我的问题。

答案 15 :(得分:1)

正如@Athasach所说,根据jQuery文档,$.ajaxSetup({cache:false})除了GET和HEAD请求之外不会起作用。

最好还是从服务器发回Cache-Control: no-cache标头。它提供了更清晰的关注点分离。

当然,这不适用于您不属于您的项目的服务网址。在这种情况下,您可以考虑从服务器代码代理第三方服务,而不是从客户端代码调用它。

答案 16 :(得分:1)

如果您使用的是.net ASP MVC,请通过在端点函数上添加以下属性来禁用控制器操作上的缓存: [OutputCacheAttribute(VaryByParam =" *",Duration = 0,NoStore = true)]

答案 17 :(得分:0)

添加标题

headers: {
                'Cache-Control':'no-cache'
            }

答案 18 :(得分:-3)

将Math.random()附加到请求网址