自从升级到iOS 6以来,我们看到Safari的web视图可以自由缓存$。ajax调用。这是在一个PhoneGap应用程序的上下文中,所以它使用Safari WebView。我们的美元。ajax调用是POST方法,我们有缓存设置为false {cache:false},但这仍然发生。我们尝试手动添加一个时间戳到头部,但它没有帮助。

我们做了更多的研究,发现Safari只返回具有静态函数签名的web服务的缓存结果,并且在每次调用之间不会改变。例如,想象一个函数是这样的:

getNewRecordID(intRecordType)

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

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


我们发现的解决方法是修改函数签名,像这样:

getNewRecordID(intRecordType, strTimestamp)

然后总是传递一个TimeStamp参数,并在服务器端丢弃这个值。这就解决了这个问题。


当前回答

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

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

如果用户使用代理来隐藏他的真实位置,那么避免缓存的唯一方法就是请求中的时间戳,如果没有使用的话。

例如:

/ajax_helper.php?ts=3211321456

然后每个缓存管理器你必须通过没有找到相同的URL在缓存库和去重新下载页面内容。

其他回答

简单的解决方案,所有的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,请检查您所选择的库的文档。它们可能有相似的功能。

我在一个PhoneGap应用程序中也遇到了这个问题。我用JavaScript函数getTime()解决了这个问题,方法如下:

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

我花了几个小时才想明白。如果苹果能通知开发者这个缓存问题就好了。

这个JavaScript代码片段与jQuery和jQuery Mobile一起工作:

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

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

为了解决添加到主屏幕的WebApps的这个问题,需要遵循投票最多的两个解决方案。需要在web服务器上关闭缓存,以防止新的请求继续缓存,并且需要在每个post请求中添加一些随机输入,以便已经缓存的请求能够通过。请参考我的帖子:

iOS6 -有一种方法来清除缓存ajax POST请求的webapp添加到主屏幕?

警告:给那些通过在请求中添加时间戳而没有关闭服务器缓存来实现解决方案的人。如果你的应用被添加到主屏幕,每一个帖子的响应现在都将被缓存,清除safari缓存不会清除它,它似乎不会过期。除非有人有办法清除它,否则这看起来像一个潜在的内存泄漏!

这就是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);