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

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

我们做了更多的研究,发现Safari只是返回具有静态功能签名且不会因呼叫而改变的Web服务的缓存结果。 例如,想象一个叫做如下的函数:

getNewRecordID(intRecordType)

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

必须在苹果急于使iOS 6 zip令人印象深刻,他们对缓存设置太满意了。 有没有其他人在iOS 6上看到这种行为? 如果是这样,究竟是什么导致了它?


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

getNewRecordID(intRecordType, strTimestamp)

然后总是传入一个TimeStamp参数,并在服务器端丢弃该值。 这解决了这个问题。 我希望这能帮助其他像我一样在这个问题上花费15个小时的可怜的灵魂!


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

我发现阻止这种缓存在全局级发生的唯一方式是设置“缓存控制:无缓存”,而不必将随机查询串转换为服务调用结束。

所以:

  • 无缓存控制或过期头= iOS6 Safari将缓存
  • 缓存控制最大年龄= 0,立即过期= iOS6的Safari将缓存
  • 缓存控制:no-cache = iOS6 Safari不会缓存
  • 我怀疑苹果公司正在利用HTTP第9.5节关于POST的规范:

    对此方法的响应不可缓存,除非响应包含适当的Cache-Control或Expires标头字段。 但是,303(请参阅其他)响应可用于指导用户代理检索可缓存资源。

    所以理论上你可以缓存POST回复......谁知道。 但没有其他浏览器制造商曾经认为,直到现在这将是一个好主意。 但是,如果没有设置Cache-Control或Expires标头,那么这并不代表缓存。 所以它一定是一个错误。

    下面是我在Apache配置的正确位中使用的目标,因为它发生时我实际上不想缓存任何东西,甚至得到。 我不知道的是如何设置这只适用于POSTs。

    Header set Cache-Control "no-cache"
    

    更新:只注意到我没有指出只有当POST是相同的时候,所以更改POST数据或URL的任何一个,你都没问题。 所以你可以像其他地方提到的那样只是向URL或一些POST数据添加一些随机数据。

    更新:如果你希望在Apache中这样做,你可以将“no-cache”限制为POST:

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

    我希望这可以用于其他开发人员在这一边撞墙的其他开发人员。 我发现以下任何一项都会阻止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()中指定的设置,因此您需要再次添加标头。


    假设你使用jQuery,简单的解决所有的web服务请求:

    $.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 prefilter的调用。

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

    链接地址: http://www.djcxy.com/p/1633.html

    上一篇: Is Safari on iOS 6 caching $.ajax results?

    下一篇: How to search for a user by name using Spotify Web API