简体   繁体   English

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

[英]Is Safari on iOS 6 caching $.ajax results?

Since the upgrade to iOS 6, we are seeing Safari's web view take the liberty of caching $.ajax calls.自从升级到 iOS 6 以来,我们看到 Safari 的 web 视图冒昧地缓存$.ajax调用。 This is in the context of a PhoneGap application so it is using the Safari WebView.这是在 PhoneGap 应用程序的上下文中,因此它使用的是 Safari WebView。 Our $.ajax calls are POST methods and we have cache set to false {cache:false} , but still this is happening.我们的$.ajax调用是POST方法,我们将缓存设置为 false {cache:false} ,但这种情况仍在发生。 We tried manually adding a TimeStamp to the headers but it did not help.我们尝试将TimeStamp手动添加到标题中,但没有帮助。

We did more research and found that Safari is only returning cached results for web services that have a function signature that is static and does not change from call to call.我们进行了更多研究,发现 Safari 仅返回具有静态函数签名且不会随调用而变化的 Web 服务的缓存结果。 For instance, imagine a function called something like:例如,想象一个名为的函数,如下所示:

getNewRecordID(intRecordType)

This function receives the same input parameters over and over again, but the data it returns should be different every time.这个函数一遍遍地接收相同的输入参数,但是每次返回的数据应该都不一样。

Must be in Apple's haste to make iOS 6 zip along impressively they got too happy with the cache settings.一定是苹果公司急于让 iOS 6 快速升级,他们对缓存设置太满意了。 Has anyone else seen this behavior on iOS 6?有没有其他人在 iOS 6 上看到过这种行为? If so, what exactly is causing it?如果是这样,究竟是什么原因造成的?


The workaround that we found was to modify the function signature to be something like this:我们发现的解决方法是将函数签名修改为如下所示:

getNewRecordID(intRecordType, strTimestamp)

and then always pass in a TimeStamp parameter as well, and just discard that value on the server side.然后始终传递一个TimeStamp参数,并在服务器端丢弃该值。 This works around the issue.这解决了这个问题。

After a bit of investigation, turns out that Safari on iOS6 will cache POSTs that have either no Cache-Control headers or even "Cache-Control: max-age=0".经过一番调查,结果表明 iOS6 上的 Safari 会缓存没有 Cache-Control 标头甚至“Cache-Control: max-age=0”的 POST。

The only way I've found of preventing this caching from happening at a global level rather than having to hack random querystrings onto the end of service calls is to set "Cache-Control: no-cache".我发现阻止这种缓存在全局级别发生而不是必须在服务调用结束时破解随机查询字符串的唯一方法是设置“缓存控制:无缓存”。

So:所以:

  • No Cache-Control or Expires headers = iOS6 Safari will cache没有 Cache-Control 或 Expires 标头 = iOS6 Safari 将缓存
  • Cache-Control max-age=0 and an immediate Expires = iOS6 Safari will cache Cache-Control max-age=0 和一个立即 Expires = iOS6 Safari 将缓存
  • Cache-Control: no-cache = iOS6 Safari will NOT cache缓存控制:no-cache = iOS6 Safari 不会缓存

I suspect that Apple is taking advantage of this from the HTTP spec in section 9.5 about POST:我怀疑 Apple 正在从关于 POST 的第 9.5 节中的 HTTP 规范中利用这一点:

Responses to this method are not cacheable, unless the response includes appropriate Cache-Control or Expires header fields.对此方法的响应不可缓存,除非响应包含适当的 Cache-Control 或 Expires 标头字段。 However, the 303 (See Other) response can be used to direct the user agent to retrieve a cacheable resource.但是,303(参见其他)响应可用于指示用户代理检索可缓存资源。

So in theory you can cache POST responses...who knew.所以理论上你可以缓存 POST 响应......谁知道呢。 But no other browser maker has ever thought it would be a good idea until now.但直到现在,还没有其他浏览器制造商认为这是一个好主意。 But that does NOT account for the caching when no Cache-Control or Expires headers are set, only when there are some set.但是当没有设置 Cache-Control 或 Expires 标头时,这不考虑缓存,只有当有一些设置时。 So it must be a bug.所以应该是bug。

Below is what I use in the right bit of my Apache config to target the whole of my API because as it happens I don't actually want to cache anything, even gets.下面是我在 Apache 配置的正确位中使用的内容来定位我的整个 API,因为碰巧我实际上并不想缓存任何东西,甚至是获取。 What I don't know is how to set this just for POSTs.我不知道如何仅为 POST 设置它。

Header set Cache-Control "no-cache"

Update: Just noticed that I didn't point out that it is only when the POST is the same, so change any of the POST data or URL and you're fine.更新:刚刚注意到我没有指出只有当 POST 相同时,所以更改任何 POST 数据或 URL 就可以了。 So you can as mentioned elsewhere just add some random data to the URL or a bit of POST data.所以你可以像其他地方提到的那样只向 URL 添加一些随机数据或一些 POST 数据。

Update: You can limit the "no-cache" just to POSTs if you wish like this in Apache:更新:如果您希望在 Apache 中这样,您可以将“无缓存”限制为 POST:

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

I hope this can be of use to other developers banging their head against the wall on this one.我希望这对其他开发人员在这个问题上撞墙有用。 I found that any of the following prevents Safari on iOS 6 from caching the POST response:我发现以下任何一项都会阻止 iOS 6 上的 Safari 缓存 POST 响应:

  • adding [cache-control: no-cache] in the request headers在请求头中添加 [cache-control: no-cache]
  • adding a variable URL parameter such as the current time添加一个可变的 URL 参数,例如当前时间
  • adding [pragma: no-cache] in the response headers在响应头中添加 [pragma: no-cache]
  • adding [cache-control: no-cache] in the response headers在响应头中添加 [cache-control: no-cache]

My solution was the following in my Javascript (all my AJAX requests are POST).我的解决方案是我的 Javascript 中的以下内容(我所有的 AJAX 请求都是 POST)。

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

I also add the [pragma: no-cache] header to many of my server responses.我还将 [pragma: no-cache] 标头添加到我的许多服务器响应中。

If you use the above solution be aware that any $.ajax() calls you make that are set to global: false will NOT use the settings specified in $.ajaxSetup(), so you will need to add the headers in again.如果您使用上述解决方案,请注意您进行的任何 $.ajax() 调用都设置为 global: false 将不会使用 $.ajaxSetup() 中指定的设置,因此您需要再次添加标头。

Simple solution for all your web service requests, assuming you're using jQuery:假设您使用的是 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()
    }));
});

Read more about the jQuery prefilter call here .在此处阅读有关 jQuery 预过滤器调用的更多信息。

If you aren't using jQuery, check the docs for your library of choice.如果您不使用 jQuery,请查看您选择的库的文档。 They may have similar functionality.它们可能具有相似的功能。

I just had this issue as well in a PhoneGap application.我刚刚在PhoneGap应用程序中也遇到了这个问题。 I solved it by using the JavaScript function getTime() in the following manner:我通过以下方式使用 JavaScript 函数getTime()了这个问题:

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

I wasted a few hours figuring this out.我浪费了几个小时来弄清楚这一点。 It would have been nice of Apple to notify developers of this caching issue.苹果公司最好通知开发人员这个缓存问题。

I had the same problem with a webapp getting data from ASP.NET webservice我在 webapp 从 ASP.NET webservice 获取数据时遇到了同样的问题

This worked for me:这对我有用:

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

Finally, I've a solution to my uploading problem.最后,我找到了上传问题的解决方案。

In JavaScript:在 JavaScript 中:

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

In PHP :PHP 中

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

From my own blog post iOS 6.0 caching Ajax POST requests :从我自己的博客文章iOS 6.0 缓存 Ajax POST 请求

How to fix it: There are various methods to prevent caching of requests.如何修复:有多种方法可以防止缓存请求。 The recommended method is adding a no-cache header.推荐的方法是添加一个 no-cache 标头。 This is how it is done.这是如何完成的。

jQuery: jQuery:

Check for iOS 6.0 and set Ajax header like this:检查 iOS 6.0 并像这样设置 Ajax 标头:

$.ajaxSetup({ cache: false });

ZeptoJS: ZeptoJS:

Check for iOS 6.0 and set the Ajax header like this:检查 iOS 6.0 并像这样设置 Ajax 标头:

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

Server side服务器端

Java:爪哇:

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

Make sure to add this at the top the page before any data is sent to the client.在将任何数据发送到客户端之前,请确保在页面顶部添加此项。

.NET 。网

Response.Cache.SetNoStore();

Or要么

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

PHP PHP

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

This JavaScript snippet works great with jQuery and jQuery Mobile:这个 JavaScript 片段非常适合 jQuery 和 jQuery Mobile:

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

Just place it somewhere in your JavaScript code (after jQuery is loaded, and best before you do AJAX requests) and it should help.只需将它放在 JavaScript 代码中的某个位置(在加载 jQuery 之后,最好在执行 AJAX 请求之前),它应该会有所帮助。

You can also fix this issue by modifying the jQuery Ajax function by doing the following (as of 1.7.1) to the top of the Ajax function (function starts at line 7212).您还可以通过在Ajax函数的顶部(函数从第 7212 行开始)执行以下操作(从 1.7.1 开始)修改jQuery Ajax函数来解决此问题。 This change will activate the built-in anti-cache feature of jQuery for all POST requests.此更改将为所有 POST 请求激活 jQuery 的内置反缓存功能。

(The full script is available at http://dl.dropbox.com/u/58016866/jquery-1.7.1.js .) (完整的脚本可在http://dl.dropbox.com/u/58016866/jquery-1.7.1.js 。)

Insert below line 7221:在第 7221 行下方插入:

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

Then modify the following (starting at line ~7497).然后修改以下内容(从 ~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 : "");
    }
}

To:到:

// 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 : "");
}

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

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

This is an update of Baz1nga's answer.这是 Baz1nga 答案的更新。 Since options.data is not an object but a string I just resorted to concatenating the timestamp:由于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();
  }
});

In order to resolve this issue for WebApps added to the home screen, both of the top voted workarounds need to be followed.为了解决添加到主屏幕的 Web 应用程序的此问题,需要遵循两种投票最多的解决方法。 Caching needs to be turned off on the webserver to prevent new requests from being cached going forward and some random input needs to be added to every post request in order for requests that have already been cached to go through.需要在网络服务器上关闭缓存以防止新请求被缓存,并且需要向每个发布请求添加一些随机输入,以便已经缓存的请求通过。 Please refer to my post:请参考我的帖子:

iOS6 - Is there a way to clear cached ajax POST requests for webapp added to home screen? iOS6 - 有没有办法清除添加到主屏幕的 webapp 缓存的 ajax POST 请求?

WARNING: to anyone who implemented a workaround by adding a timestamp to their requests without turning off caching on the server.警告:对于通过向其请求添加时间戳而不关闭服务器上的缓存来实施变通方法的任何人。 If your app is added to the home screen, EVERY post response will now be cached, clearing safari cache doesn't clear it and it doesn't seem to expire.如果您的应用程序被添加到主屏幕,现在每个帖子响应都将被缓存,清除 safari 缓存不会清除它,它似乎也不会过期。 Unless someone has a way to clear it, this looks like a potential memory leak!除非有人有办法清除它,否则这看起来像是潜在的内存泄漏!

Things that DID NOT WORK for me with an iPad 4/iOS 6:使用 iPad 4/iOS 6 对我不起作用的事情:

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

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

Adding cache: false to my jQuery ajax call向我的 jQuery ajax 调用添加缓存:false

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

Only this did the trick:只有这样才能奏效:

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

That's the work around for GWT-RPC这就是 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);    

My workaround in ASP.NET (pagemethods, webservice, etc.)我在ASP.NET 中的解决方法(页面方法、网络服务等)

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

While adding cache-buster parameters to make the request look different seems like a solid solution, I would advise against it, as it would hurt any application that relies on actual caching taking place.虽然添加缓存破坏器参数使请求看起来不同似乎是一个可靠的解决方案,但我建议不要这样做,因为它会损害任何依赖实际缓存发生的应用程序。 Making the APIs output the correct headers is the best possible solution, even if that's slightly more difficult than adding cache busters to the callers.使 API 输出正确的标头是最好的解决方案,即使这比向调用者添加缓存破坏器稍微困难一些。

For those that use Struts 1 , here is how I fixed the issue.对于那些使用Struts 1 ,这是我解决问题的方法。

web.xml网页.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 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() {
    }

}

I was able to fix my problem by using a combination of $.ajaxSetup and appending a timestamp to the url of my post (not to the post parameters/body).我能够通过组合使用 $.ajaxSetup 并将时间戳附加到我的帖子的网址(而不是帖子参数/正文)来解决我的问题。 This based on the recommendations of previous answers这基于先前答案的建议

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

I think you have already resolved your issue, but let me share an idea about web caching.我想你已经解决了你的问题,但让我分享一个关于网络缓存的想法。

It is true you can add many headers in each language you use, server side, client side, and you can use many other tricks to avoid web caching, but always think that you can never know from where the client are connecting to your server, you never know if he are using a Hotel “Hot-Spot” connection that uses Squid or other caching products.确实,您可以在您使用的每种语言中添加许多标头,服务器端,客户端,并且您可以使用许多其他技巧来避免 Web 缓存,但始终认为您永远无法知道客户端从哪里连接到您的服务器,你永远不知道他是否在使用使用 Squid 或其他缓存产品的酒店“热点”连接。

If the users are using proxy to hide his real position, etc… the real only way to avoid caching is the timestamp in the request also if is unused.如果用户使用代理来隐藏他的真实位置等……避免缓存的真正唯一方法是请求中的时间戳,如果未使用。

For example:例如:

/ajax_helper.php?ts=3211321456

Then every cache manager you have to pass didnt find the same URL in the cache repository and go re-download the page content.然后您必须传递的每个缓存管理器都没有在缓存存储库中找到相同的 URL,并重新下载页面内容。

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.根据应用程序,您现在可以在 iOS 6 中使用 Safari>Advanced>Web Inspector 解决问题,这对这种情况很有帮助。

Connect the phone to Safari on a Mac an then use the developer menu to trouble shoot the web app.将手机连接到 Mac 上的 Safari,然后使用开发人员菜单对 Web 应用程序进行故障排除。

Clear the website data on the iPhone after update to iOS6, including specific to the app using a Web View.更新到 iOS6 后清除 iPhone 上的网站数据,包括特定于使用 Web 视图的应用程序。 Only one app had an issue and this solved it during IOS6 Beta testing way back, since then no real problems.只有一个应用程序有问题,这在 IOS6 Beta 测试期间解决了它,从那时起就没有真正的问题。

You may need to look at your app as well, check out NSURLCache if in a WebView in a custom app.您可能还需要查看您的应用程序,如果在自定义应用程序的 WebView 中,请查看 NSURLCache。

https://developer.apple.com/library/ios/#documentation/Cocoa/Reference/Foundation/Classes/NSURLCache_Class/Reference/Reference.html#//apple_ref/doc/uid/TP40003754 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参考: $.ajax 调用

I found one workaround that makes me curious as to why it works.我找到了一种解决方法,让我好奇它为什么起作用。 Before reading Tadej's answer concerning ASP.NET web service, I was trying to come up with something that would work.在阅读 Tadej 关于 ASP.NET Web 服务的回答之前,我试图想出一些可行的方法。

And I'm not saying that it's a good solution, but I just wanted to document it here.我并不是说这是一个好的解决方案,但我只是想在这里记录它。

main page: includes a JavaScript function, checkStatus().主页:包括一个 JavaScript 函数 checkStatus()。 The method calls another method which uses a jQuery AJAX call to update the html content.该方法调用另一个方法,该方法使用 jQuery AJAX 调用来更新 html 内容。 I used setInterval to call checkStatus().我使用 setInterval 来调用 checkStatus()。 Of course, I ran into the caching problem.当然,我遇到了缓存问题。

Solution: use another page to call the update.解决方法:使用另一个页面调用更新。

On the main page, I set a boolean variable, runUpdate, and added the following to the body tag:在主页上,我设置了一个布尔变量 runUpdate,并将以下内容添加到 body 标记中:

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

In the of helper.html:在 helper.html 中:

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

So, if checkStatus() is called from the main page, I get the cached content.因此,如果从主页调用 checkStatus(),我将获得缓存的内容。 If I call checkStatus from the child page, I get updated content.如果我从子页面调用 checkStatus,我会得到更新的内容。

While my login and signup pages works like a charm in Firefox, IE and Chrome... I've been struggling with this issue in Safari for IOS and OSX, few months ago I found a workaround on the SO.虽然我的登录和注册页面在 Firefox、IE 和 Chrome 中就像一个魅力......我一直在为 IOS 和 OSX 的 Safari 解决这个问题,几个月前我在 SO 上找到了一个解决方法。

<body onunload="">

OR via javascript或通过javascript

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

This is kinda ugly thing but works for a while.这有点丑陋,但可以使用一段时间。

I don't know why, but returning null to the onunload event the page do not get cached in Safari.我不知道为什么,但是向onunload事件返回 null 页面不会在 Safari 中缓存。

In Ruby's Sinatra 在Ruby的Sinatra中

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

We found that older iPhones and iPads, running iOS versions 9 & 10, occasionally return bogus blank AJAX results, perhaps due to Apple's turning down CPU speed.我们发现,运行 iOS 9 和 10 版本的旧 iPhone 和 iPad 偶尔会返回虚假的空白 AJAX 结果,这可能是由于 Apple 降低了 CPU 速度。 When returning the blank result, iOS does not call the server, as if returning a result from cache.返回空白结果时,iOS 不会调用服务器,就像从缓存中返回结果一样。 Frequency varies widely, from roughly 10% to 30% of AJAX calls return blank.频率变化很大,从大约 10% 到 30% 的 AJAX 调用返回空白。

The solution is hard to believe.解决方案令人难以置信。 Just wait 1s and call again.只需等待 1 秒,然后再次调用。 In our testing, only one repeat was all that was ever needed, but we wrote the code to call up to 4 times.在我们的测试中,只需要重复一次,但我们编写了最多可调用 4 次的代码。 We're not sure if the 1s wait is required, but we didn't want to risk burdening our server with bursts of repeated calls.我们不确定是否需要 1s 等待,但我们不想冒着重复调用突发而给服务器带来负担的风险。

We found the problem happened with two different AJAX calls, calling on different API files with different data.我们发现问题发生在两个不同的 AJAX 调用中,调用具有不同数据的不同 API 文件。 But I'm concerned it could happen on any AJAX call.但我担心它可能发生在任何 AJAX 调用中。 We just don't know because we don't inspect every AJAX result and we don't test every call multiple times on old devices.我们只是不知道,因为我们不会检查每个 AJAX 结果,也不会在旧设备上多次测试每个调用。

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

When the problem happens, there's usually only one AJAX call going on.当问题发生时,通常只有一个 AJAX 调用在进行。 So it's not due to overlapping AJAX calls.所以这不是由于重叠的 AJAX 调用。 Sometimes the problem happens when the device is busy, but sometimes not, and without DevTools we don't really know what's happening at the time.有时问题会在设备繁忙时发生,但有时不会,如果没有 DevTools,我们真的不知道当时发生了什么。

iOS 13 doesn't do this, nor Chrome or Firefox. iOS 13 不会这样做,Chrome 或 Firefox 也不会。 We don't have any test devices running iOS 11 or 12. Perhaps someone else could test those?我们没有任何运行 iOS 11 或 12 的测试设备。也许其他人可以测试这些设备?

I'm noting this here because this question is the top Google result when searching for this problem.我在这里注意到这一点,因为在搜索此问题时,此问题是 Google 的最高结果。

It worked with ASP.NET only after adding the pragma:no-cache header in IIS .只有在IIS 中添加pragma:no-cache标头后,它才能与ASP.NET一起使用。 Cache-Control: no-cache was not enough. Cache-Control: no-cache是不够的。

I suggest a workaround to modify the function signature to be something like this:我建议一种解决方法来修改函数签名是这样的:

getNewRecordID(intRecordType, strTimestamp) and then always pass in a TimeStamp parameter as well, and just discard that value on the server side. getNewRecordID(intRecordType, strTimestamp) 然后总是传入一个 TimeStamp 参数,并在服务器端丢弃该值。 This works around the issue.这解决了这个问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM