在 IE8中 AJAX 的意外缓存导致的结果

对于来自 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然后登录并开始一个新的拼图来检查它。

在我测试过的所有浏览器(谷歌 Chrome,火狐,Safari,Internet Explorer)中,它在 IE 中都能很好地工作。在 IE第一次中,所有的东西都被注入得很好,但是在那之后,它甚至从来没有打电话给 /game/getpuzzleinfo。好像缓存了结果什么的。

如果我把调用改成 $.post("/game/getpuzzleinfo", ... IE 浏览器就可以正常工作,但是火狐就不工作了。

有人能解释一下为什么 IE 缓存我的 $.get ajax 调用吗?

更新

根据下面的建议,我已经将 ajax 请求更改为这个,这解决了我的问题:

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

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

正如 Marr75所提到的,GET是缓存的。

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

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

你可以这样做:

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

IE 因其对 Ajax 响应的高速缓存而臭名昭著,当你使用 jQuery 时,你可以设置一个全局选项:

$.ajaxSetup({
cache: false
});

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

请注意,如果在需要缓存的地方进行其他 Ajax 调用,这也将禁用这些调用。在这种情况下,切换到使用 $。方法,并为必要的请求显式启用该选项。

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

这就是我为 Ajax 打来的电话所做的:

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

我觉得挺好的。

这里的答案对于那些使用 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/

刚刚写了一篇关于这个问题的博客,只是使用了 ExtJS http://thecodeabode.blogspot.com/2010/10/cache-busting-ajax-requests-in-ie.html )

问题在于,当我使用特定的 url 重写格式时,我不能使用传统的查询字符串参数(?Param = value) ,因此我将缓存破坏参数写为一个发布的变量,而不是... ..。我认为使用 POST 变量比使用 GET 要安全一些,因为很多 MVC 框架都使用这种模式

Protocol://host/controller/action/param1/param2

所以变量名到值的映射丢失了,参数被简单地堆叠起来... 所以当使用 GET 缓存终结器参数时

即协议://host/controller/action/param1/param2/no _ cache 122300201

No _ cache 122300201可能会被误认为是一个可能具有默认值的 $param3参数

也就是说。

Public 函数操作($param1,$param2,$param3 = “ default value”) { //..// }

POSTED 缓存终结器不可能发生这种情况

如果您正在调用 ashx 页面,您也可以使用以下代码禁用服务器上的缓存:

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

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

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

如果你正在使用 ASP.NET MVC,在控制器操作上添加这一行就足够了:

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


}

IE 有权进行这种缓存; 为了确保项目没有被缓存,应该相应地设置标题。

如果使用 ASP.NET MVC,可以编写一个 ActionFilter; 在 OnResultExecuted中,选中 filterContext.HttpContext.Request.IsAjaxRequest()。如果是这样,设置响应的过期头: filterContext.HttpContext.Response.Expires = -1;

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

有些人喜欢使用 Cache-Control: no-Cache 头 而不是过期,区别在于:
Cache-Control: NO-cache-绝对没有缓存
过期: -1-浏览器“通常”联系 对该页进行更新的 Web 服务器 但是,该页仍然保留在磁盘缓存中 在适当的情况下使用,而不需要与遥控器联系 Web 服务器,例如使用 BACK 和 FORWARD 按钮时 访问导航历史记录或浏览器处于脱机模式时。