自从升级到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参数,并在服务器端丢弃这个值。这就解决了这个问题。
我们发现,运行iOS 9和10版本的旧iphone和ipad偶尔会返回虚假的空白AJAX结果,可能是由于苹果降低了CPU速度。当返回空白结果时,iOS不调用服务器,就像从缓存中返回结果一样。频率差异很大,大约10%到30%的AJAX调用返回空白。
解决方案令人难以置信。请稍等片刻,然后再打来。在我们的测试中,只需要重复一次,但我们编写的代码最多可以调用4次。我们不确定是否需要1s等待,但我们不想冒着重复调用导致服务器负担过重的风险。
我们发现这个问题发生在两个不同的AJAX调用中,调用不同的API文件,使用不同的数据。但我担心在任何AJAX调用中都可能发生这种情况。我们只是不知道,因为我们没有检查每个AJAX结果,也没有在旧设备上多次测试每个调用。
这两个问题AJAX调用都使用:POST,异步= true, setRequestHeader = ('Content-Type', 'application/x-www-form-urlencoded')
当问题发生时,通常只有一个AJAX调用在进行。所以这不是由于重叠的AJAX调用。有时问题发生在设备忙的时候,但有时不是,没有DevTools,我们真的不知道当时发生了什么。
iOS 13没有这个功能,Chrome和Firefox也没有。我们没有任何运行iOS 11或12的测试设备。也许其他人可以测试一下?
我在这里注意到这一点是因为在搜索这个问题时,这个问题是谷歌的顶部结果。
简单的解决方案,所有的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,请检查您所选择的库的文档。它们可能有相似的功能。
我希望这能对其他在这个问题上绞尽脑汁的开发人员有所帮助。我发现以下任何一个阻止Safari在iOS 6上缓存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()中指定的设置,因此您将需要再次添加头部。
我认为你已经解决了你的问题,但是让我分享一个关于web缓存的想法。
确实,你可以在你使用的每种语言中添加许多头文件,服务器端,客户端,你可以使用许多其他技巧来避免web缓存,但总是认为你永远不知道客户端从哪里连接到你的服务器,你永远不知道他是否使用酒店的“热点”连接,使用Squid或其他缓存产品。
如果用户使用代理来隐藏他的真实位置,那么避免缓存的唯一方法就是请求中的时间戳,如果没有使用的话。
例如:
/ajax_helper.php?ts=3211321456
然后每个缓存管理器你必须通过没有找到相同的URL在缓存库和去重新下载页面内容。