iOS 6 上的 Safari 是否缓存 $.ajax 结果?

Is Safari on iOS 6 caching $.ajax results?

提问人:user1684978 提问时间:9/20/2012 最后编辑:Sreeram Nairuser1684978 更新时间:7/7/2023 访问量:144976

问:

自从升级到 iOS 6 以来,我们看到 Safari 的 Web 视图可以自由地缓存调用。这是在PhoneGap应用程序的上下文中,因此它使用Safari WebView。我们的调用是方法,我们将缓存设置为 false ,但这种情况仍在发生。我们尝试手动将 a 添加到标题中,但没有帮助。$.ajax$.ajaxPOST{cache:false}TimeStamp

我们做了更多的研究,发现 Safari 只返回 Web 服务的缓存结果,这些 Web 服务具有静态的函数签名,并且不会随调用而变化。例如,想象一个函数,称为:

getNewRecordID(intRecordType)

此函数一遍又一遍地接收相同的输入参数,但它每次返回的数据都应该不同。

一定是苹果急于让iOS 6拉链,令人印象深刻,他们对缓存设置太满意了。有没有人在 iOS 6 上看到过这种行为?如果是这样,究竟是什么原因造成的?


我们发现的解决方法是将函数签名修改为如下所示:

getNewRecordID(intRecordType, strTimestamp)

然后始终传入一个参数,并在服务器端丢弃该值。这可以解决此问题。TimeStamp

JavaScript jQuery Ajax 缓存 mobile-safari

评论

192赞 Kieran 9/20/2012
这绝对令人震惊。我们也刚刚花了几个小时试图弄清楚是什么东西停止了工作。我们的 AJAX 登录名执行 POST(并且也有防止缓存的标头)正在被 Safari 缓存,因此它只是返回与上次相同的 JSON,甚至没有尝试服务器......难以置信!我们将不得不破解一个修复程序,但你永远不应该缓存 POST,这太疯狂了。
16赞 ChrisF 9/21/2012
将解决方案作为答案发布,而不是对问题的更新。
50赞 James M. Greene 9/21/2012
POST 请求是非幂等的,这意味着除非响应明确建议通过其响应标头缓存,否则不应缓存它们。
6赞 Mathias Bynens 9/23/2012
要让 Apple 解决此问题,请在 bugreport.apple.com 提交错误。我也做过同样的事情。
11赞 Benjamin Brizzi 9/24/2012
Mark Nottingham(IETF HTTPbis 工作组主席)今天写了一篇有趣的博文:mnot.net/blog/2012/09/24/caching_POST

答:

45赞 Bashevis 9/20/2012 #1

我只是在PhoneGap应用程序中也遇到了这个问题。我通过以下方式使用 JavaScript 函数解决了它:getTime()

var currentTime = new Date();
var n = currentTime.getTime();
postUrl = "http://www.example.com/test.php?nocache="+n;
$.post(postUrl, callbackFunction);

我浪费了几个小时来弄清楚这一点。如果 Apple 将此缓存问题通知开发人员,那就太好了。

评论

1赞 cthulhu 9/21/2012
我打算评论将 IN 用作 或 的选项,但根据文档,这些参数被忽略了;jQuery将“从不缓存”发布请求,但不会考虑浏览器。也许更简洁的选择是使用 向请求添加时间戳。{cache:false}$.post()$.ajaxSetup()$.ajaxPrefilter()
0赞 rusly 11/23/2013
我花了将近 5 个小时来解决这个问题,最后添加时间戳就可以了.请参阅此处 stackoverflow.com/questions/14733772/...function send_ajax(my_data,refresh)
450赞 Kieran 9/21/2012 #2

经过一番调查,事实证明 iOS6 上的 Safari 将缓存没有 Cache-Control 标头甚至“Cache-Control: max-age=0”的 POST。

我发现防止这种缓存在全局级别发生而不必在服务调用结束时破解随机查询字符串的唯一方法是设置“Cache-Control: no-cache”。

所以:

  • 没有 Cache-Control 或 Expires 标头 = iOS6 Safari 将缓存
  • Cache-Control max-age=0 和立即过期 = iOS6 Safari 将缓存
  • Cache-Control: no-cache = iOS6 Safari 不会缓存

我怀疑 Apple 正在利用 HTTP 规范中关于 POST 的第 9.5 节中的这一点:

对此方法的响应是不可缓存的,除非响应 包括相应的 Cache-Control 或 Expires 标头字段。然而 303(请参阅其他)响应可用于将用户代理定向到 检索可缓存资源。

所以从理论上讲,你可以缓存 POST 响应......谁知道呢。但直到现在,还没有其他浏览器制造商认为这是一个好主意。但是,当没有设置 Cache-Control 或 Expires 标头时,这不会考虑缓存,只有当设置了一些标头时。所以它一定是一个错误。

以下是我在 Apache 配置的正确部分中使用的内容,以针对我的整个 API,因为碰巧我实际上不想缓存任何东西,甚至不想缓存。我不知道的是如何仅为 POST 设置它。

Header set Cache-Control "no-cache"

更新:刚刚注意到我没有指出只有当 POST 相同时才有,所以更改任何 POST 数据或 URL 就可以了。因此,正如其他地方所述,您只需向 URL 添加一些随机数据或一些 POST 数据即可。

更新:如果您希望在 Apache 中这样,您可以将“无缓存”限制为 POST:

SetEnvIf Request_Method "POST" IS_POST
Header set Cache-Control "no-cache" env=IS_POST

评论

8赞 Kango_V 9/21/2012
我明白 Apple 在这方面的发展方向,但即使我们的响应不包含任何 Cache-Control 或 Expires 标头,我们也看到了对 POST 请求的缓存响应。这个实例是 iOS6 不应该缓存和发送每个请求的。这没有发生。
140赞 David H 9/21/2012
您引用的 HTTP 规范部分并不能证明 iOS 6 的缓存行为是合理的。默认行为应该是不缓存 POST 响应(即,当未定义“Cache-Control”标头时)。该行为违反了规范,应被视为错误。任何构建 xml/json api Web 服务的人都应该用“Cache-control: no-cache”来修饰他们的 POST 响应,以解决此问题。
40赞 James M. Greene 9/21/2012
POST 请求是非幂等的,这意味着除非响应明确建议通过其响应标头缓存,否则不应缓存它们。
4赞 Matthew Flaschen 9/22/2012
正如大卫所说,这显然违反了你引用的句子。如果没有“Cache-Control 或 Expires 标头字段”,则显然不包括相应的此类标头。然而,你自己的调查显示它在这种情况下会缓存。请编辑您的答案。
3赞 Daniel Hallqvist 9/26/2012
有谁知道结果在设备上缓存了多长时间?我试过杀死野生动物园并重新启动我的手机,但它仍然被缓存。我知道它适用于清除浏览器缓存,但我想知道曾经遇到过问题的用户需要多长时间才能消失。不是每个人都会想到清除他们的缓存......
43赞 Tadej 9/21/2012 #3

我在 Web 应用程序从 Web 服务获取数据时遇到了同样的问题 ASP.NET

这对我有用:

public WebService()
{
    HttpContext.Current.Response.Cache.SetCacheability(HttpCacheability.NoCache);
    ...
}

评论

2赞 Mark Brittingham 11/12/2012
谢谢!我快要疯了,试图弄清楚为什么iPhone的行为与其他所有平台都如此不同。此 ASP.NET专用解决方案为我节省了大量时间。
0赞 Brian Ogden 4/29/2013
在 iOS6 上不起作用,在线程末尾看到我的答案
1赞 Alexandre 4/9/2015
请!!!!设置仅在IOS 6上应用此条件的条件,内容缓存对任何应用程序都至关重要。
70赞 Baz1nga 9/21/2012 #4

针对所有 Web 服务请求的简单解决方案,假设您使用的是 jQuery:

$.ajaxPrefilter(function (options, originalOptions, jqXHR) {
    // you can use originalOptions.type || options.type to restrict specific type of requests
    options.data = jQuery.param($.extend(originalOptions.data||{}, { 
      timeStamp: new Date().getTime()
    }));
});

在此处阅读有关 jQuery 预过滤器调用的更多信息。

如果您没有使用 jQuery,请查看所选库的文档。它们可能具有类似的功能。

评论

3赞 Alexandre 9/24/2012
It doesn't work to me, server responds: "Invalid primitive JSON: timeStamp" asp.net / iis 7.5
3赞 Karussell 9/24/2012
what about the $.ajax({ "cache": false ...}) ? will it work as it append a _=[TIMESTAMP]? (I don't own such a device to test it)
0赞 Sam Shiles 9/27/2012
I have posted a full implementation of the solution proposed by Karussell. See my answer below.
1赞 Brett Hannah 10/2/2012
@Karussell. Just tried setting $.ajax({ "cache": false ...}). This doesn't resolve the issue for POST requests on iOS6. Presumably because JQuery as per their docs assumes no browser is stupid enough to cache post requests. "Pages fetched with POST are never cached, so the cache and ifModified options in jQuery.ajaxSetup() have no effect on these requests."
1赞 Chris Muench 10/16/2012
This doesn't work. It doesn't merge post parameters. The post by Dave is a better solution.
0赞 Steven Strauss 9/22/2012 #5

Depending on the app you can trouble shoot the issue now in iOS 6 using Safari>Advanced>Web Inspector so that is helpful with this situation.

Connect the phone to Safari on a Mac an then use the developer menu to trouble shoot the web app.

Clear the website data on the iPhone after update to iOS6, including specific to the app using a Web View. Only one app had an issue and this solved it during IOS6 Beta testing way back, since then no real problems.

You may need to look at your app as well, check out NSURLCache if in a WebView in a custom app.

https://developer.apple.com/library/ios/#documentation/Cocoa/Reference/Foundation/Classes/NSURLCache_Class/Reference/Reference.html#//apple_ref/doc/uid/TP40003754

I guess depending on the true nature of your problem, implementation, etc. ..

Ref: $.ajax calls

评论

0赞 Kris Giesing 10/8/2012
While this doesn't directly address the original question, it's very useful information for being able to troubleshoot on-devices issues in general, so I'm up-voting it.
25赞 goker 9/22/2012 #6

Finally, I've a solution to my uploading problem.

In JavaScript:

var xhr = new XMLHttpRequest();
xhr.open("post", 'uploader.php', true);
xhr.setRequestHeader("pragma", "no-cache");

In PHP:

header('cache-control: no-cache');
2赞 Ivo Jansch 9/24/2012 #7

虽然添加 cache-buster 参数以使请求看起来不同似乎是一个可靠的解决方案,但我建议不要这样做,因为它会损害任何依赖于实际缓存的应用程序。使 API 输出正确的标头是最好的解决方案,即使这比向调用方添加缓存破坏器稍微困难一些。

评论

1赞 Sam Shiles 9/28/2012
虽然我同意你大多数情况,但我认为这个问题的真正解决方案是让苹果正确地实现HTTP。考虑到这一点,我不会责怪很多开发人员在那之前实现最简单的解决方案。对我来说,修改jquery实现是最简单的修复方法,因为它允许我进行一次编辑,并确信它对我的整个网站都有效。
3赞 Alexandre 9/24/2012 #8

我在 ASP.NET 中的解决方法(页面方法、网络服务等)

protected void Application_BeginRequest(object sender, EventArgs e)
{
    Response.Cache.SetCacheability(HttpCacheability.NoCache);
}
-1赞 Boris 9/25/2012 #9

只有在 IIS 中添加标头后,它才适用于 ASP.NET。 还不够。pragma:no-cacheCache-Control: no-cache

7赞 Sam Shiles 9/27/2012 #10

您还可以通过修改 jQuery Ajax 函数来解决此问题,方法是对 Ajax 函数的顶部执行以下操作(从 1.7.1 开始)(函数从第 7212 行开始)。此更改将为所有 POST 请求激活 jQuery 的内置反缓存功能。

(完整脚本可在 。http://dl.dropbox.com/u/58016866/jquery-1.7.1.js

在第 7221 行下方插入:

if (options.type === "POST") {
    options.cache = false;
}

然后修改以下内容(从第 ~7497 行开始)。

if (!s.hasContent) {
    // If data is available, append data to URL
    if (s.data) {
        s.url += (rquery.test(s.url) ? "&" : "?") + s.data;
        // #9682: remove data so that it's not used in an eventual retry
        delete s.data;
    }

    // Get ifModifiedKey before adding the anti-cache parameter
    ifModifiedKey = s.url;

    // Add anti-cache in URL if needed
    if (s.cache === false) {
        var ts = jQuery.now(),
        // Try replacing _= if it is there
        ret = s.url.replace(rts, "$1_=" + ts);

        // If nothing was replaced, add timestamp to the end.
        s.url = ret + ((ret === s.url) ? (rquery.test(s.url) ? "&" : "?") + "_=" + ts : "");
    }
}

自:

// More options handling for requests with no content
if (!s.hasContent) {
    // If data is available, append data to URL
    if (s.data) {
        s.url += (rquery.test(s.url) ? "&" : "?") + s.data;
        // #9682: remove data so that it's not used in an eventual retry
        delete s.data;
    }

    // Get ifModifiedKey before adding the anti-cache parameter
    ifModifiedKey = s.url;
}

// Add anti-cache in URL if needed
if (s.cache === false) {
    var ts = jQuery.now(),
    // Try replacing _= if it is there
    ret = s.url.replace(rts, "$1_=" + ts);

    // If nothing was replaced, add timestamp to the end.
    s.url = ret + ((ret === s.url) ? (rquery.test(s.url) ? "&" : "?") + "_=" + ts : "");
}

评论

4赞 Andreas Louv 11/1/2012
这不是更改jQuery或任何您不拥有的代码的好方法。(每次要更新版本时,都必须再次进行更改。(或者其他开发人员更新了程序,程序不起作用))
0赞 Sam Shiles 11/1/2012
如果您需要最快的解决方案来减轻 Apple 的愚蠢行为,这是一种完全有效的方法。该解决方案已用于解决每天收到数百万次点击的大型网站的问题,它使我们能够通过更改一个文件来做到这一点。
0赞 Andreas Louv 11/1/2012
你可以看看它,让你在发出ajax请求之前修改它。您可以使用更优化和更新的安全代码进行存档。jQuery.ajaxPrefiler
1赞 Sam Shiles 11/1/2012
preFilter 方法的问题在于需要注册过滤器。如果你有一个通用脚本,在每个页面加载时运行,那么很好,但如果你没有,你将不得不为每个使用ajax的页面设置preFilter。我面对的场景是,我们有一个 JQ 文件的公共位置,该文件被用作 7+ 个独立网站的资源。由于这个错误,我们每小时损失了数千英镑,我建议的方法使我们能够通过更改一个文件在最短的时间内解决它。我原则上同意你的看法,但有时你必须务实!
0赞 Andreas Louv 11/1/2012
然后,您可以再次将其添加到该文件的末尾。你解决了它,你的公司一定为你感到高兴。
5赞 fbader 9/28/2012 #11

为了解决添加到主屏幕的 WebApps 的此问题,需要遵循两个投票最高的解决方法。需要在 Web 服务器上关闭缓存,以防止将来缓存新请求,并且需要向每个 POST 请求添加一些随机输入,以便已经缓存的请求通过。请参考我的帖子:

iOS6 - 有没有办法清除添加到主屏幕的 Web 应用程序的缓存 ajax POST 请求?

警告:通过在未关闭服务器上的缓存的情况下向请求添加时间戳来实施变通方法的任何人。如果您的应用程序已添加到主屏幕,则现在将缓存每个帖子响应,清除 safari 缓存不会清除它,并且它似乎不会过期。除非有人有办法清除它,否则这看起来像是潜在的内存泄漏!

评论

0赞 Eydun 10/5/2012
所有响应都会缓存到手机上的文件或内存中吗?
0赞 ShadeTreeDeveloper 1/20/2013
我的情况并非如此。我在我的 url 中附加了一个时间戳(不是帖子参数),无论是在从 Safari 浏览还是保存到主屏幕时,它都能正常工作。
0赞 CM Kanode 10/8/2012 #12

我发现了一种解决方法,让我好奇它为什么有效。在阅读 Tadej 关于 Web 服务的回答之前 ASP.NET 我试图想出一些可行的方法。

我并不是说这是一个很好的解决方案,但我只是想在这里记录下来。

main page:包含一个 JavaScript 函数 checkStatus()。该方法调用另一个方法,该方法使用 jQuery AJAX 调用来更新 html 内容。我使用 setInterval 调用 checkStatus()。当然,我遇到了缓存问题。

解决方案:使用另一个页面调用更新。

在主页上,我设置了一个布尔变量 runUpdate,并将以下内容添加到 body 标签中:

<iframe src="helper.html" style="display: none; visibility: hidden;"></iframe>

在帮助程序.html中:

<meta http-equiv="refresh" content="5">
<script type="text/javascript">
    if (parent.runUpdate) { parent.checkStatus(); }
</script>

因此,如果从主页调用 checkStatus(),我会得到缓存的内容。如果我从子页面调用 checkStatus,我会得到更新的内容。

4赞 Spiff 10/12/2012 #13

这就是 GWT-RPC 的解决方法

class AuthenticatingRequestBuilder extends RpcRequestBuilder 
{
       @Override
       protected RequestBuilder doCreate(String serviceEntryPoint) 
       {
               RequestBuilder requestBuilder = super.doCreate(serviceEntryPoint);           
               requestBuilder.setHeader("Cache-Control", "no-cache");

               return requestBuilder;
       }
}

AuthenticatingRequestBuilder builder = new AuthenticatingRequestBuilder();
((ServiceDefTarget)myService).setRpcRequestBuilder(builder);    
149赞 Dave 10/12/2012 #14

我希望这对其他开发人员在这个问题上撞墙有用。我发现以下任何一种情况都会阻止 iOS 6 上的 Safari 缓存 POST 响应:

  • 在请求头中添加 [cache-control: no-cache]
  • 添加变量 URL 参数,例如当前时间
  • 在响应标头中添加 [pragma: no-cache]
  • 在响应标头中添加 [cache-control: no-cache]

我的解决方案是在我的 Javascript 中如下(我所有的 AJAX 请求都是 POST)。

$.ajaxSetup({
    type: 'POST',
    headers: { "cache-control": "no-cache" }
});

我还将 [pragma: no-cache] 标头添加到我的许多服务器响应中。

如果您使用上述解决方案,请注意,您所做的任何设置为 global: false 的 $.ajax() 调用都不会使用 $.ajaxSetup() 中指定的设置,因此您需要再次添加标头。

评论

4赞 Nicholas Shanks 11/13/2012
这是该错误的正确解决方案。错误是 iOS 6 将处理来自其缓存的 POST 请求,而不是将它们发送到服务器。该错误不是它缓存来自 POST 请求的响应(这是允许的)。如果仍希望响应从缓存中检索到的 POST 请求,以便对该 URI 的后续 GET 请求,请使用此解决方案。
2赞 Tom W Hall 11/27/2012
这对我有用,但我不明白怎么做。我已经在我的ajaxSetup中指定了cache: false,并查看请求标头,这归结为Cache-Control:no-cache和Pragma:no-cache - 但它仍然会在iPad上缓存。然后,当我将headers: { “cache-control”: “no-cache” }添加到ajaxSetup中时,它会将Cache-Control标头加倍为“no-cache,no-cache” - 并停止缓存。这是怎么回事?
0赞 George Filippakos 1/2/2013
完美工作 - 您还可以将参数 $.ajax({type: 'POST', headers: { 'cache-control': 'no-cache' }, etc.}) 添加到请求中
0赞 zakdances 3/20/2013
什么是 [pragma: no-cache]?编译指示键是做什么用的?
0赞 germankiwi 5/21/2013
我也认为这是最好的方法,而不是使用附加参数的解决方法。我们只在需要它的调用中添加了它,对于始终具有相同返回的调用,缓存对最终用户来说可能是一件好事。
6赞 Lars Høidahl 10/17/2012 #15

GWT-RPC 服务的快速解决方法是将其添加到所有远程方法中:

getThreadLocalResponse().setHeader("Cache-Control", "no-cache");

评论

0赞 YoungDinosaur 11/9/2012
我们大多数人在他们的 GWT 部署中都有数百种远程方法。是否有一种通用方法为所有请求设置缓存控制标头?
6赞 remcoder 10/25/2012 #16

这是 Baz1nga 答案的更新。由于它不是一个对象,而是一个字符串,我只是求助于连接时间戳:options.data

$.ajaxPrefilter(function (options, originalOptions, jqXHR) {
  if (originalOptions.type == "post" || options.type == "post") {

    if (options.data && options.data.length)
      options.data += "&";
    else
      options.data = "";

    options.data += "timeStamp=" + new Date().getTime();
  }
});

评论

1赞 Nicholas Shanks 11/13/2012
添加时间戳是个坏主意,请尝试 Dave 的解决方案。
16赞 kiranvj 11/14/2012 #17

从我自己的博客文章 iOS 6.0 缓存 Ajax POST 请求

如何解决:有多种方法可以防止缓存请求。推荐的方法是添加无缓存标头。这就是它是如何完成的。

###jQuery:

检查 iOS 6.0 并设置 Ajax 标头,如下所示:

$.ajaxSetup({ cache: false });

###ZeptoJS:

检查 iOS 6.0 并设置 Ajax 标头,如下所示:

$.ajax({
    type: 'POST',
    headers : { "cache-control": "no-cache" },
    url : ,
    data:,
    dataType : 'json',
    success : function(responseText) {…}

##Server 面

###Java:

httpResponse.setHeader("Cache-Control", "no-cache, no-store, must-revalidate");

请确保在将任何数据发送到客户端之前将其添加到页面顶部。

###.NET

Response.Cache.SetNoStore();

Response.Cache.SetCacheability(System.Web.HttpCacheability.NoCache);

###PHP

header('Cache-Control: no-cache, no-store, must-revalidate'); // HTTP 1.1.
header('Pragma: no-cache'); // HTTP 1.0.

评论

2赞 Aran Mulholland 11/22/2012
.NET stackoverflow.com/questions/10011780/ 的一个很好的无缓存属性...
1赞 cbmeeks 1/10/2013 #18

对于那些使用的人,这是我解决问题的方法。Struts 1

网络.xml

<filter>
    <filter-name>SetCacheControl</filter-name>
    <filter-class>com.example.struts.filters.CacheControlFilter</filter-class>
</filter>

<filter-mapping>
    <filter-name>SetCacheControl</filter-name>
    <url-pattern>*.do</url-pattern>
    <http-method>POST</http-method>
</filter-mapping>

com.example.struts.filters.CacheControlFilter.js

package com.example.struts.filters;

import java.io.IOException;
import java.util.Date;
import javax.servlet.*;
import javax.servlet.http.HttpServletResponse;

public class CacheControlFilter implements Filter {

        public void doFilter(ServletRequest request, ServletResponse response,
                     FilterChain chain) throws IOException, ServletException {

        HttpServletResponse resp = (HttpServletResponse) response;
        resp.setHeader("Expires", "Mon, 18 Jun 1973 18:00:00 GMT");
        resp.setHeader("Last-Modified", new Date().toString());
        resp.setHeader("Cache-Control", "no-store, no-cache, must-revalidate, max-age=0, post-check=0, pre-check=0");
        resp.setHeader("Pragma", "no-cache");

        chain.doFilter(request, response);
    }

    public void init(FilterConfig filterConfig) throws ServletException {
    }

    public void destroy() {
    }

}
2赞 ShadeTreeDeveloper 1/20/2013 #19

我能够通过使用 $.ajaxSetup 的组合并将时间戳附加到我的帖子的 url(而不是帖子参数/正文)来解决我的问题。这是基于先前答案的建议

$(document).ready(function(){
    $.ajaxSetup({ type:'POST', headers: {"cache-control","no-cache"}});

    $('#myForm').submit(function() {
        var data = $('#myForm').serialize();
        var now = new Date();
        var n = now.getTime();
        $.ajax({
            type: 'POST',
            url: 'myendpoint.cfc?method=login&time='+n,
            data: data,
            success: function(results){
                if(results.success) {
                    window.location = 'app.cfm';
                } else {
                    console.log(results);
                    alert('login failed');
                }
            }
        });
    });
});
8赞 Jonathan 1/26/2013 #20

此 JavaScript 代码段非常适合 jQuery 和 jQuery Mobile:

$.ajaxSetup({
    cache: false,
    headers: {
        'Cache-Control': 'no-cache'
    }
});

只需将它放在 JavaScript 代码中的某个位置(在加载 jQuery 之后,最好在执行 AJAX 请求之前),它应该会有所帮助。

5赞 Brian Ogden 4/29/2013 #21

在iPad 4 / iOS 6上对我不起作用的事情:

我的请求包含:Cache-Control:no-cache

//asp.net's:
HttpContext.Current.Response.Cache.SetCacheability(HttpCacheability.NoCache)

将 cache: false 添加到我的 jQuery ajax 调用中

 $.ajax(
        {
            url: postUrl,
            type: "POST",
            cache: false,
            ...

只有这样才成功:

var currentTime = new Date();
var n = currentTime.getTime();
postUrl = "http://www.example.com/test.php?nocache="+n;
$.post(postUrl, callbackFunction);

评论

0赞 Brian Ogden 5/10/2013
反对票是为了什么?这是重要的信息 cache:false 不适用于 iPad4/iOS6,//asp.net 也不适用于: HttpContext.Current.Response.Cache.SetCacheability(HttpCacheability.NoCache)
0赞 cowbert 1/16/2018
对于后代:截至 2017 年,使用 query 参数附加 url,因此不再需要手动附加时间戳。$.ajaxcache: false_=Date.prototype.getTime()
1赞 Lanello 6/13/2014 #22

我想你已经解决了你的问题,但让我分享一个关于网络缓存的想法。

诚然,你可以用你使用的每种语言添加许多标头,服务器端、客户端,你可以使用许多其他技巧来避免网络缓存,但总是认为你永远无法知道客户端从哪里连接到你的服务器,你永远不知道他是否正在使用使用 Squid 或其他缓存产品的酒店“热点”连接。

如果用户使用代理来隐藏他的真实位置等......避免缓存的真正唯一方法是请求中的时间戳,如果未使用。

例如:

/ajax_helper.php?ts=3211321456

然后,您必须传递的每个缓存管理器都没有在缓存存储库中找到相同的URL,然后重新下载页面内容。

评论

0赞 Giacomo1968 12/3/2015
老答案,但我的两分钱:这通常是很好的建议,并且被大多数有能力的 Web 开发人员所理解,但在 jQuery 的特定情况下,如果您制作了一个并设置了选项,那么 jQuery 本身将自动在幕后添加缓存破坏,而无需您执行任何其他操作。$.ajax{cache:false}
0赞 Adriano Rosa 7/20/2014 #23

虽然我的登录和注册页面在 Firefox、IE 和 Chrome 中就像一个魅力......我一直在为IOS和OSX的Safari中的问题而苦苦挣扎,几个月前,我在SO上找到了解决方法。

<body onunload="">

或通过 javascript

<script type="text/javascript">
window.onunload = function(e){
    e.preventDefault();
    return;
};
</script>   

这有点丑陋,但可以工作一段时间。

我不知道为什么,但是将null返回到页面未在Safari中缓存的事件。onunload

-2赞 fred1234 7/29/2016 #24

我建议一种解决方法,将函数签名修改为如下所示:

getNewRecordID(intRecordType, strTimestamp) 然后始终传入 TimeStamp 参数,并在服务器端丢弃该值。这可以解决此问题。

1赞 CaptureWiz 1/26/2020 #25

我们发现,运行 iOS 版本 9 和 10 的旧款 iPhoneiPad 偶尔会返回虚假的空白 AJAX 结果,这可能是由于 Apple 降低了 CPU 速度。返回空白结果时,iOS 不会调用服务器,就像从缓存中返回结果一样。频率差异很大,大约有 10% 到 30% 的 AJAX 调用返回空白。

解决方案令人难以置信。只需等待 1 秒,然后再次拨打。在我们的测试中,只需要重复一次,但我们编写的代码最多可以调用 4 次。我们不确定是否需要 1 秒等待,但我们不想冒着因重复调用而给我们的服务器带来负担的风险。

我们发现问题发生在两个不同的 AJAX 调用上,调用具有不同数据的不同 API 文件。但我担心它可能发生在任何 AJAX 调用中。我们只是不知道,因为我们不会检查每个 AJAX 结果,也不会在旧设备上多次测试每个调用。

AJAX 调用使用的两个问题:POST, Asynchronously = true, setRequestHeader = ('Content-Type', 'application/x-www-form-urlencoded')

当问题发生时,通常只有一个 AJAX 调用在进行。因此,这不是由于重叠的 AJAX 调用。有时,当设备繁忙时会发生问题,但有时不会,如果没有 DevTools,我们真的不知道当时发生了什么。

iOS 13 不会这样做,Chrome 或 Firefox 也不会这样做。我们没有任何运行 iOS 11 或 12 的测试设备。也许其他人可以测试这些?

我在这里注意到这一点,因为在搜索这个问题时,这个问题是谷歌的顶级结果。