IE8意外缓存AJAX结果


135

我对来自JQuery Ajax请求的Internet Explorer缓存结果存在严重问题。

我的网页上有标题,每次用户导航到新页面时标题都会更新。页面加载后,我就执行此操作

$.get("/game/getpuzzleinfo", null, function(data, status) {
    var content = "<h1>Wikipedia Maze</h1>";
    content += "<p class='endtopic'>Looking for <span><a title='Opens the topic you are looking for in a separate tab or window' href='" + data.EndTopicUrl + "' target='_blank'>" + data.EndTopic + "<a/></span></p>";
    content += "<p class='step'>Step <span>" + data.StepCount + "</span></p>";
    content += "<p class='level'>Level <span>" + data.PuzzleLevel.toString() + "</span></p>";
    content += "<p class='startover'><a href='/game/start/" + data.PuzzleId.toString() + "'>Start Over</a></p>";

    $("#wikiheader").append(content);

}, "json");

它只是将标头信息注入页面。您可以通过访问www.wikipediamaze.com进行检查,然后登录并开始创建新拼图。

在我测试过的每种浏览器(谷歌浏览器,Firefox,Safari,Internet Explorer)中, IE 之外,它都很好用。首次在IE中注入Eveything效果很好,但此后甚至再也没有调用/game/getpuzzleinfo。就像它已经缓存了结果一样。

如果我将呼叫更改为$.post("/game/getpuzzleinfo", ...IE,则接听就很好。但是随后Firefox退出了工作。

有人可以就为什么IE缓存我的$.getAjax调用对此有所了解吗?

更新

根据以下建议,我已将ajax请求更改为此,从而解决了我的问题:

$.ajax({
    type: "GET",
    url: "/game/getpuzzleinfo",
    dataType: "json",
    cache: false,
    success: function(data) { ... }
});

8
感谢您的询问。我无言以对,这种浏览器的行为。
jjohn 2011年

1
好问题,非常酷的网站。好主意。
MikeMurko 2011年

Answers:


177

IE以其积极地缓存Ajax响应而臭名昭著。使用jQuery时,可以设置全局选项:

$.ajaxSetup({
    cache: false
});

这将导致jQuery向请求查询字符串添加随机值,从而防止IE缓存响应。

请注意,如果您要缓存的地方还有其他的Ajax调用,这也会对那些缓存禁用。在这种情况下,请切换为使用$ .ajax()方法,并为必要的请求显式启用该选项。

有关更多信息,请参见http://docs.jquery.com/Ajax/jQuery.ajaxSetup


1
您还可以在网址末尾添加时间戳。不知道为什么jQuery不采用这种方法。
埃里克·约翰逊

14
@Eric:这就是jQuery内部的功能-“ cache:false”选项只是告诉它做到这一点。
NickFitz

为什么jquery默认不启用它?
speedplane

我只是注意到,当您尝试通过调用IE 8中的主页时,缓存选项不起作用/。将其更改为/index.php或完整的URL。或自己添加一些假参数/?f=f
Hugo Delsing 2013年

8

正如marr75所提到的,GET's被缓存。

有两种方法可以解决此问题。除了修改响应头之外,您还可以将随机生成的查询字符串变量附加到目标URL的末尾。这样,每次请求IE都会认为它是一个不同的URL。

有多种方法可以做到这一点(例如,使用Math.random(),日期的变化等)。

这是您可以执行的一种方法:

var oDate = new Date();
var sURL = "/game/getpuzzleinfo?randomSeed=" + oDate.getMilliseconds();
$.get(sURL, null, function(data, status) {
    // your work
});

3

获取始终是可缓存的。一种可行的策略是编辑响应头,并告诉客户端不要缓存信息或使缓存很快过期。


这听起来像一个好主意。我将如何去做?
米卡

1
这是一个加载的问题,取决于您的服务器端代码。请参阅维基百科条目“ HTTP标头列表”以获取一些指导。示例:缓存控制:无缓存到期时间:1994年12月1日,星期四,格林尼治标准时间基本上,您需要将这些响应标头附加到http响应中。在ASP.NET,Ruby和PHP中,这相当简单。只需查找您正在使用的服务器端语言+修改响应头即可。
2009年

3
而且,这完全不是对Jquery的批评(我喜欢这个库),添加随机查询字符串参数的方法是安全的,但对客户端不礼貌(它会使它们保留在缓存中永远不会使用的项目)再次)。
2009年

2

如果要调用ashx页面,则还可以使用以下代码在服务器上禁用缓存:

context.Response.Cache.SetCacheability(HttpCacheability.NoCache);
context.Response.Cache.SetRevalidation(HttpCacheRevalidation.AllCaches); 

1

这是我为ajax调用所做的:

var url = "/mypage.aspx";
// my other vars i want to add go here
url = url + "&sid=" + Math.random();
// make ajax call

对我来说效果很好。


1

NickFitz提供了一个很好的答案,但是您也需要在IE9中关闭缓存。为了只针对IE8和IE9,您可以这样做。

<!--[if lte IE 9]>
<script>
    $.ajaxSetup({
        cache: false
    });
</script>
<![endif]-->

0

对于使用jQuery或出于某种原因直接使用xmlHttpRequest对象的人,这里的答案非常有帮助。

如果您使用的是自动生成的Microsoft服务代理,则解决起来并不容易。

诀窍是在事件处理程序中使用Sys.Net.WebRequestManager.add_invokingRequest方法更改请求url:

networkRequestEventArgs._webRequest._url = networkRequestEventArgs._webRequest._url + '&nocache=' + new Date().getMilliseconds(); 

我已经在此发布了博客:http: //yoavniran.wordpress.com/2010/04/27/ie-caching-ajax-results-how-to-fix/


0

刚刚使用ExtJS在这个确切的问题上写了一个博客(http://thecodeabode.blogspot.com/2010/10/cache-busting-ajax-requests-in-ie.html

问题是因为我使用的是特定的url重写格式,所以我无法使用常规的查询字符串参数(?param = value),因此我将缓存清除参数写为已发布的变量.....我本以为使用POST变量比使用GET更为安全,这仅仅是因为许多MVC框架都使用该模式

协议://主机/控制器/动作/参数1 /参数2

这样就丢失了变量名到值的映射,并且仅堆叠了参数...因此,当使用GET cache buster参数时

即协议://主机/控制器/动作/参数/参数2 / no_cache122300201

no_cache122300201可能会误认为$ param3参数,该参数可能具有默认值

公共功能操作($ param1,$ param2,$ param3 =“默认值”){//..//}

POSTED缓存破坏程序不会发生这种情况


0

如果您使用的是ASP.NET MVC,则只需在控制器操作的顶部添加以下行即可:

[OutputCache(NoStore=true, Duration = 0, VaryByParam = "None")]
public ActionResult getSomething()
{

}

有问题的行为是在浏览器端。这个答案与服务器端的缓存有关。
Mark Sowul '16

@MarkSowul Outputcache具有3个选项:客户端,服务器和任何其他选项。IE默认使用OutputCache作为默认值,大多数都用作客户端缓存。您可以在此处查看更多详细信息dougwilsonsa.wordpress.com/2011/04/29/…–
batmaci

@MarkSowul您也可以在此处查看相关的问题和答案。您认为这也在服务器端吗?stackoverflow.com/questions/2653092/…–
batmaci

1
是的,很抱歉,您是对的-我没有意识到您的回答会同时影响服务器端缓存和客户端缓存。
Mark Sowul '16

-1

IE有权执行此缓存。为了确保不缓存该项,应相应设置标题。

如果您使用的是ASP.NET MVC,则可以编写ActionFilter; 在OnResultExecuted,检查filterContext.HttpContext.Request.IsAjaxRequest()。如果是这样,请设置响应的expire标头:filterContext.HttpContext.Response.Expires = -1;

根据http://www.dashbay.com/2011/05/internet-explorer-caches-ajax/

有些人更喜欢使用Cache-Control:no-缓存头而不是过期。区别在于:
Cache-Control:no-cache –绝对没有缓存
Expires:-1 –浏览器“通常”通过条件If-Modified-Since请求联系Web服务器以更新该页面。但是,该页面保留在磁盘缓存中,并在适当的情况下使用而无需联系远程Web服务器,例如,当使用BACK和FORWARD按钮访问导航历史记录时,或者当浏览器处于脱机模式时。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.