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

问题描述 投票:255回答:21

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

在QueryString中添加一些随机字符串似乎可以解决此问题(我使用new Date().toString()),但这听起来像是在砍死。

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

javascript jquery ajax browser-cache
21个回答
236
投票

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

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

编辑:这个答案已有好几年了。它仍然有效(因此我没有删除它),但是现在有更好/更干净的方法可以实现这一目标。我的首选是this方法,但是如果要在页面的生命周期内禁用every请求的缓存,this答案也很有用。


5
投票

真正的问题是,为什么不缓存它?如果由于它一直在更改而不应该被缓存,则服务器应指定不缓存资源。如果它有时只是更改(因为它所依赖的资源之一可能会更改),并且如果客户端代码有一种了解的方式,则可以将伪参数附加到从某个哈希或上次修改日期计算出的url上这些资源(这是我们在Microsoft Ajax脚本资源中所做的工作,因此可以永久地缓存它们,但仍可以在出现时提供新版本)。如果客户端不知道更改,则正确的方法应该是服务器正确处理HEAD请求并告诉客户端是否使用缓存的版本。在我看来,像添加随机参数或从客户端告诉永不缓存是错误的,因为可缓存性是服务器资源的属性,因此应在服务器端确定。另一个要问自己的问题是,该资源是真正通过GET提供还是通过POST提供?这是一个语义问题,但是也有安全隐患(只有在服务器允许GET的情况下,攻击才会起作用)。 POST将不会被缓存。


4
投票

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

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


3
投票

除了给出的出色答案之外,还有一小部分:如果您正在为没有javascript的用户使用非ajax备份解决方案运行,那么无论如何,您都必须正确设置这些服务器端标头。这不是不可能的,尽管我理解那些放弃的人;)

我确定SO上还有另一个问题,它将为您提供适当的全套标题。我不是完全被定罪的胶束回复涵盖所有基础100%。


3
投票

对于那些在移动Safari上使用cache$.ajaxSetup()选项的用户,您似乎必须为POST使用时间戳记,因为移动Safari也会对其进行缓存。根据$.ajax()上的文档(从$.ajaxSetup()定向到):

将缓存设置为false只能正确处理HEAD和GET请求。它通过在GET参数后面附加“ _ = {timestamp}”来工作。对于其他类型的请求,不需要此参数,但在IE8中,当对GET已请求的URL进行POST时,则为该参数。

因此,在上述情况下,仅设置该选项不会对您有帮助。


2
投票

基本上只是在Ajax中添加cache:false;,您认为其中的内容会随着进度的进行而改变。而内容在那里不会改变的地方,您可以忽略这一点。这样,您每次都会得到新的响应


2
投票

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

  1. 向查询字符串添加缓存清除令牌,例如?date = [timestamp]。在jQuery和YUI中,您可以告诉他们自动执行此操作。
  2. 使用POST而不是GET
  3. 发送明确禁止浏览器缓存的HTTP响应标头

2
投票

现在,就像这样,通过启用/禁用ajax请求中的缓存选项很容易做到这一点

$(function () {
    var url = 'your url goes here';
    $('#ajaxButton').click(function (e) {
        $.ajax({
            url: url,
            data: {
                test: 'value'
            },
                cache: true, //cache enabled, false to reverse
                complete: doSomething
            });
        });
    });
    //ToDo after ajax call finishes
    function doSomething(data) {
        console.log(data);
    }
});

1
投票

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

[OutputCache(NoStore = true,持续时间= 0,VaryByParam =“ *”)]

公共类TestController:Controller

这将阻止浏览器进行缓存。

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

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


1
投票

正如@Athasach所说,根据jQuery文档,$.ajaxSetup({cache:false})除了GET和HEAD请求外,将无法使用。

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

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


1
投票

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


510
投票

无论您使用哪种jQuery方法($ .get,$。ajax等,以下内容都将阻止以后所有AJAX请求的缓存)

$.ajaxSetup({ cache: false });

0
投票

添加标题

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

-3
投票

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


313
投票

JQuery的$ .get()将缓存结果。代替

$.get("myurl", myCallback)

您应该使用$ .ajax,这将使您关闭缓存:

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

23
投票

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

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

21
投票

这里的所有答案都在请求的URL上留下一个脚印,它将显示在服务器的访问日志中。

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

至少在Chrome上有效,结果将是:

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

13
投票

个人而言,我认为查询字符串方法比尝试在服务器上设置标头更可靠-无法保证代理或浏览器也不会仅仅缓存它(某些浏览器比其他浏览器更糟糕-不命名)。

我通常使用Math.random(),但使用日期我没有发现任何错误(您不应以足够快的速度进行AJAX请求以两次获得相同的值)。


11
投票

按照文档:http://api.jquery.com/jquery.ajax/

您可以将cache属性用于:

$.ajax({
    method: "GET",
    url: "/Home/AddProduct?",
    data: { param1: value1, param2: value2},
    cache: false,
    success: function (result) {
        // TODO
    }
});

5
投票

当然,“打破缓存”技术可以完成工作,但是如果服务器向客户端指示不应缓存响应,则首先不会发生这种情况。在某些情况下,缓存响应有时是有益的。让服务器决定数据的正确寿命。您可能需要稍后进行更改。从服务器执行操作比从UI代码中的许多不同位置执行操作容易得多。

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


5
投票

如何使用POST请求而不是GET ...?(无论如何您应该...)

© www.soinside.com 2019 - 2024. All rights reserved.