jQuery 在 IE8 中意外缓存 AJAX 结果
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1013637/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Unexpected Caching of AJAX results in IE8
提问by Micah
I'm having a serious issue with Internet Explorer caching results from a JQuery Ajax request.
我在 Internet Explorer 缓存来自 JQuery Ajax 请求的结果时遇到了严重问题。
I have header on my web page that gets updated every time a user navigates to a new page. Once the page is loaded I do this
我的网页上有标题,每次用户导航到新页面时都会更新。加载页面后,我会执行此操作
$.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");
It just injects header info into the page. You can check it out by going to www.wikipediamaze.comand then logging in and starting a new puzzle.
它只是将标题信息注入页面。您可以通过访问www.wikipediamaze.com然后登录并开始一个新谜题来查看它。
In every browser I've tested (Google Chrome, Firefox, Safari, Internet Explorer) it works great exceptin IE. Eveything gets injected just fine in IE the first timebut after that it never even makes the call to /game/getpuzzleinfo
. It's like it has cached the results or something.
在我测试过的每个浏览器(Google Chrome、Firefox、Safari、Internet Explorer)中,它都运行良好,但在 IE 中除外。第一次在 IE 中注入一切都很好,但之后它甚至从未调用/game/getpuzzleinfo
. 就好像它已经缓存了结果什么的。
If I change the call to $.post("/game/getpuzzleinfo", ...
IE picks it up just fine. But then Firefox quits working.
如果我将呼叫更改为$.post("/game/getpuzzleinfo", ...
IE接听就好了。但随后 Firefox 停止工作。
Can someone please shed some light on this as to why IE is caching my $.get
ajax calls?
有人可以解释一下为什么 IE 缓存我的$.get
ajax 调用吗?
UPDATE
更新
Per the suggestion below, I've changed my ajax request to this, which fixed my problem:
根据以下建议,我已将 ajax 请求更改为此,解决了我的问题:
$.ajax({
type: "GET",
url: "/game/getpuzzleinfo",
dataType: "json",
cache: false,
success: function(data) { ... }
});
回答by NickFitz
IE is notorious for its aggressive caching of Ajax responses. As you're using jQuery, you can set a global option:
IE 因其对 Ajax 响应的积极缓存而臭名昭著。当您使用 jQuery 时,您可以设置一个全局选项:
$.ajaxSetup({
cache: false
});
which will cause jQuery to add a random value to the request query string, thereby preventing IE from caching the response.
这将导致 jQuery 向请求查询字符串添加一个随机值,从而阻止 IE 缓存响应。
Note that if you have other Ajax calls going on where you do want caching, this will disable it for those too. In that case, switch to using the $.ajax() method and enable that option explicitly for the necessary requests.
请注意,如果您在需要缓存的地方有其他 Ajax 调用,这也会为这些调用禁用它。在这种情况下,切换到使用 $.ajax() 方法并为必要的请求显式启用该选项。
See http://docs.jquery.com/Ajax/jQuery.ajaxSetupfor more info.
有关更多信息,请参阅http://docs.jquery.com/Ajax/jQuery.ajaxSetup。
回答by Tom
As marr75mentioned, GET
's are cached.
正如marr75提到的,GET
's 被缓存。
There are a couple of ways to combat this. Aside from modifying the response header, you can also append a randomly generated query string variable to the end of the targeted URL. This way, IE will think it is a different URL each time it is requested.
有几种方法可以解决这个问题。除了修改响应头之外,您还可以将随机生成的查询字符串变量附加到目标 URL 的末尾。这样,IE 在每次请求时都会认为它是不同的 URL。
There are multiple ways to do this (such as using Math.random()
, a variation on the date, etc).
有多种方法可以做到这一点(例如使用Math.random()
、日期的变体等)。
Here's one way you can do it:
这是您可以做到的一种方法:
var oDate = new Date();
var sURL = "/game/getpuzzleinfo?randomSeed=" + oDate.getMilliseconds();
$.get(sURL, null, function(data, status) {
// your work
});
回答by marr75
Gets are always cacheable. One strategy that may work is to edit the response header and tell the client to not cache the information or to expire the cache very soon.
获取总是可缓存的。一种可行的策略是编辑响应头并告诉客户端不要缓存信息或很快使缓存过期。
回答by Andrej Benedik
If you are calling ashx page you can also disable caching on the server with the following code:
如果您正在调用 ashx 页面,您还可以使用以下代码禁用服务器上的缓存:
context.Response.Cache.SetCacheability(HttpCacheability.NoCache);
context.Response.Cache.SetRevalidation(HttpCacheRevalidation.AllCaches);
回答by Stuart Hallows
NickFitz gives a good answer, but you'll need to turn the caching off in IE9 as well. In order to target just IE8 and IE9 you could do this;
NickFitz 给出了一个很好的答案,但您还需要在 IE9 中关闭缓存。为了仅针对 IE8 和 IE9,您可以这样做;
<!--[if lte IE 9]>
<script>
$.ajaxSetup({
cache: false
});
</script>
<![endif]-->
回答by Jason
this is what i do for ajax calls:
这就是我为 ajax 调用所做的:
var url = "/mypage.aspx";
// my other vars i want to add go here
url = url + "&sid=" + Math.random();
// make ajax call
it works pretty well for me.
它对我来说效果很好。
回答by poeticGeek
The answers here are very helpful for those who use jQuery or for some reason directly use the xmlHttpRequest object...
这里的答案对那些使用 jQuery 或出于某种原因直接使用 xmlHttpRequest 对象的人非常有帮助......
If you're using the auto-generated Microsoft service proxy its not as simple to solve.
如果您使用的是自动生成的 Microsoft 服务代理,那么解决起来就不是那么简单了。
The trick is to use Sys.Net.WebRequestManager.add_invokingRequest method in the event handler change the request url:
诀窍是在事件处理程序中使用 Sys.Net.WebRequestManager.add_invokingRequest 方法更改请求 url:
networkRequestEventArgs._webRequest._url = networkRequestEventArgs._webRequest._url + '&nocache=' + new Date().getMilliseconds();
I've blogged about this: http://yoavniran.wordpress.com/2010/04/27/ie-caching-ajax-results-how-to-fix/
我在博客上写过这个:http: //yoavniran.wordpress.com/2010/04/27/ie-caching-ajax-results-how-to-fix/
回答by Ben
Just wrote a blog on this exact issue only using ExtJS (http://thecodeabode.blogspot.com/2010/10/cache-busting-ajax-requests-in-ie.html)
刚刚使用 ExtJS 写了一篇关于这个确切问题的博客(http://thecodeabode.blogspot.com/2010/10/cache-busting-ajax-requests-in-ie.html)
The problem was as I was using a specific url rewriting format I couldn't use conventional query string params (?param=value), so I had write the cache busting parameter as a posted variable instead..... I would have thought that using POST variables are a bit safer that GET, simply because a lot of MVC frameworks use the pattern
问题是因为我使用了特定的 url 重写格式,所以我不能使用传统的查询字符串参数 (?param=value),所以我将缓存破坏参数写为一个发布的变量......我会想到使用 POST 变量比 GET 更安全,因为很多 MVC 框架都使用该模式
protocol://host/controller/action/param1/param2
协议://host/controller/action/param1/param2
and so the mapping of variable name to value is lost, and params are simply stacked... so when using a GET cache buster parameter
所以变量名到值的映射丢失了,参数只是堆叠起来......所以当使用 GET 缓存破坏参数时
i.e. protocol://host/controller/action/param1/param2/no_cache122300201
即协议://host/controller/action/param1/param2/no_cache122300201
no_cache122300201 can be mistaken for a $param3 parameter which could have a default value
no_cache122300201 可能被误认为是 $param3 参数,该参数可能具有默认值
i.e.
IE
public function action($param1, $param2, $param3 = "default value") { //..// }
public function action($param1, $param2, $param3 = "default value") { //..// }
no chance of that happening with POSTED cache busters
POSTED 缓存破坏者不可能发生这种情况
回答by batmaci
If you are using ASP.NET MVC, it is enough to add this line on top of the controller action:
如果您使用的是 ASP.NET MVC,则在控制器操作的顶部添加以下行就足够了:
[OutputCache(NoStore=true, Duration = 0, VaryByParam = "None")]
public ActionResult getSomething()
{
}
回答by Mark Sowul
IE is within its rights to do this caching; to ensure the item isn't cached, the headers should be set accordingly.
IE 有权进行这种缓存;为确保项目不被缓存,应相应地设置标题。
If you are using ASP.NET MVC, you can write an ActionFilter
; in OnResultExecuted
, check filterContext.HttpContext.Request.IsAjaxRequest()
. If so, set the response's expire header: filterContext.HttpContext.Response.Expires = -1;
如果您使用的是 ASP.NET MVC,则可以编写一个ActionFilter
; 在OnResultExecuted
,检查filterContext.HttpContext.Request.IsAjaxRequest()
。如果是这样,请设置响应的过期标头:filterContext.HttpContext.Response.Expires = -1;
As per http://www.dashbay.com/2011/05/internet-explorer-caches-ajax/:
根据http://www.dashbay.com/2011/05/internet-explorer-caches-ajax/:
Some people prefer to use the Cache - Control: no - cache header instead of expires. Here's the difference:
Cache-Control:no-cache – absolutely NO caching
Expires:-1 – the browser “usually” contacts the Web server for updates to that page via a conditional If-Modified-Since request. However, the page remains in the disk cache and is used in appropriate situations without contacting the remote Web server, such as when the BACK and FORWARD buttons are used to access the navigation history or when the browser is in offline mode.
有些人更喜欢使用 Cache - Control: no - cache header 而不是 expires。区别如下:
Cache-Control:no-cache – 绝对没有缓存
Expires:-1 – 浏览器“通常”通过条件 If-Modified-Since 请求联系 Web 服务器更新该页面。但是,该页面保留在磁盘缓存中,并在不联系远程 Web 服务器的适当情况下使用,例如当使用“后退”和“前进”按钮访问导航历史记录或浏览器处于脱机模式时。