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




jquery caching (17)

自升级到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个小时的可怜的灵魂!


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

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

iPad 4 / iOS 6 适合我的东西:

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

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

为我的jQuery ajax调用添加缓存:false

 $.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);

为了解决添加到主屏幕中的WebApps的这个问题,需要遵循顶级投票解决方法。 需要在网络服务器上关闭缓存以防止新的请求被缓存,并且需要将一些随机输入添加到每个发布请求中,以便已经缓存的请求通过。 请参考我的帖子:

iOS6 - 有没有办法清除缓存的ajax POST请求添加到主屏幕的webapp?

警告:对于通过向其请求添加时间戳而不关闭服务器上的缓存来实施解决方法的任何人。 如果您的应用程序已添加到主屏幕,则现在每个帖子的回复都会被缓存,清除Safari缓存并不会清除它,并且它似乎不会过期。 除非有人有办法清除它,这看起来像是一个潜在的内存泄漏!


从我自己的博客文章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) {…}

服务器端

Java的:

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

在将任何数据发送到客户端之前,请务必在页面顶部添加此项。

。净

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.

只有在IIS添加pragma:no-cache头后,才能与ASP.NET一起工作。 Cache-Control: no-cache是不够的。


在Ruby的Sinatra中

before '*' do
  if env['REQUEST_METHOD'] == 'POST'
    headers 'Cache-Control' => 'no-cache, no-store, must-revalidate'
  end
end

尽管我的登录页面和注册页面在Firefox,IE和Chrome中都很有魅力,但我几个月前在Safari的IOS和OSX上一直在努力解决这个问题,所以我在SO上找到了一个解决方法。

<body onunload="">

或通过JavaScript

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

这是一件有点丑陋的事情,但有一段时间。

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


您也可以通过修改jQuery Ajax函数来修复此问题,方法是对Ajax函数(函数从7212行开始)执行以下操作(从1.7.1开始)。 此更改将为所有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 : "");
}

我在ASP.NET解决方法(pagemethods,webservice等)

protected void Application_BeginRequest(object sender, EventArgs e)
{
    Response.Cache.SetCacheability(HttpCacheability.NoCache);
}

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


我有一个web应用程序从ASP.NET webservice获取数据的问题

这对我有效:

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

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

$(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');
                }
            }
        });
    });
});

最后,我解决了上传问题。

在JavaScript中:

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

PHP

header('cache-control: no-cache');

根据应用程序的不同,您可以使用Safari> Advanced> Web Inspector在iOS 6中解决问题,以便在此情况下有所帮助。

将手机连接到Mac上的Safari,然后使用开发人员菜单来解决网络应用程序的问题。

更新到iOS6后,清除iPhone上的网站数据,包括使用Web视图特定于该应用程序。 只有一个应用程序有问题,并且这在IOS6 Beta测试方式返回时解决了它,因为没有真正的问题。

您可能还需要查看您的应用,如果在自定义应用中的WebView中检查了NSURLCache。

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

我想根据你的问题的真实性质,执行情况等。

参考:$ .ajax电话


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


这个JavaScript代码片段适用于jQuery和jQuery Mobile:

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

只要把它放在你的JavaScript代码的某个地方(在jQuery加载之后,最好在你做AJAX请求之前),它应该有所帮助。


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




mobile-safari