Asp.net AJAX的意外缓存导致IE8

Asp.net AJAX的意外缓存导致IE8,asp.net,jquery,ajax,internet-explorer,Asp.net,Jquery,Ajax,Internet Explorer,我对jqueryajax请求的internetexplorer缓存结果有一个严重的问题 我的网页上有一个标题,每当用户导航到一个新页面时,它都会被更新。加载页面后,我将执行此操作 $.get("/game/getpuzzleinfo", null, function(data, status) { var content = "<h1>Wikipedia Maze</h1>"; content += "<p class='endtopic'>L

我对jqueryajax请求的internetexplorer缓存结果有一个严重的问题

我的网页上有一个标题,每当用户导航到一个新页面时,它都会被更新。加载页面后,我将执行此操作

$.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");

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

如前所述,
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调用,这也会对这些调用禁用缓存。在这种情况下,切换到使用$.ajax()方法,并为必要的请求显式启用该选项


有关更多信息,请参阅。

这是我为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\u invokingRequest方法更改请求url:

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

我在博客上写过:

刚刚用ExtJS写了一篇关于这个问题的博客( )

问题是,由于我使用的是特定的url重写格式,我无法使用传统的查询字符串params(?param=value),因此我不得不将缓存破坏参数作为一个POST变量来编写。。。。。我认为使用POST变量比GET更安全,因为很多MVC框架都使用这种模式

protocol://host/controller/action/param1/param2

所以变量名到值的映射丢失了,参数只是简单地叠加在一起。。。所以当使用GET cache buster参数时

i、 e。protocol://host/controller/action/param1/param2/no_cache122300201

不能将任何_cache122300201误认为$param3参数,该参数可能具有默认值

i、 e

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


如果您正在调用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()
。如果是,则设置响应的expire头:
filterContext.HttpContext.response.Expires=-1

根据:

有些人更喜欢使用Cache-Control:no-Cache头 而不是过期。区别如下:
缓存控制:无缓存–绝对无缓存
Expires:-1–浏览器“通常”与 Web服务器,用于通过条件 如果自请求后进行了修改。但是,该页仍保留在磁盘缓存中 在适当情况下使用,无需联系遥控器 Web服务器,例如使用后退和前进按钮 访问导航历史记录或浏览器处于脱机模式时


听起来是个好主意。我该怎么做呢?这是一个复杂的问题,取决于您的服务器端代码。请参阅wikipedia条目“HTTP头列表”,了解一些指导。示例:缓存控制:无缓存过期:Thu,1994年12月1日16:00:00 GMT基本上您需要将这些响应头附加到http响应中。它在ASP.NET、Ruby和PHP中相当简单。只需查找您正在使用的服务器端语言+修改响应头。此外,这根本不是对Jquery的批评(我喜欢这个库),添加随机查询字符串参数的方法是安全的,但对客户端来说是不礼貌的(它可能使它们保留在缓存中的项上,而这些项将永远不会被使用)。您还可以在URL的末尾添加时间戳。不确定为什么jQuery不采用这种方法。@Eric:这是jQuery内部的工作方式——“cache:false”选项只是告诉它这样做。为什么jQuery在默认情况下不启用此选项?我只是注意到,当您尝试在IE 8中请求主页时,通过调用
/
时,缓存选项不起作用。将其更改为
/index.php
或任何完整url。或者自己添加一些假的参数,比如
/?f=f
,谢谢你的提问。我说不出这个浏览器的行为。好问题,真的很酷的网站。好主意。有问题的行为在浏览器端;这个答案与服务器端的缓存有关。@MarkSowul Outputcache有三个选项:客户端、服务器和任意。IE使用OutputCache作为默认值,主要用作客户端缓存。您可以在这里@marksohul查看更多详细信息,也可以在这里查看相关问题和答案。您认为这也在服务器端吗?是的,对不起,你是对的--我不知道你的回答会影响服务器和服务器
[OutputCache(NoStore=true, Duration = 0, VaryByParam = "None")]
public ActionResult getSomething()
{

}