O Safari no iOS 6 está armazenando em cache os resultados de $ .ajax?


1072

Desde a atualização para o iOS 6, estamos vendo a visualização na Web do Safari ter a liberdade de fazer cache de $.ajaxchamadas. Isso ocorre no contexto de um aplicativo PhoneGap e, portanto, ele usa o Safari WebView. Nossas $.ajaxchamadas são POSTmétodos e temos cache definido como false {cache:false}, mas ainda está acontecendo. Tentamos adicionar manualmente um TimeStampaos cabeçalhos, mas não ajudou.

Pesquisamos mais e descobrimos que o Safari está retornando apenas resultados em cache para serviços da Web que possuem uma assinatura de função estática e que não muda de uma chamada para outra. Por exemplo, imagine uma função chamada algo como:

getNewRecordID(intRecordType)

Essa função recebe os mesmos parâmetros de entrada repetidas vezes, mas os dados retornados devem ser diferentes a cada vez.

Deve estar na pressa da Apple para fazer com que o iOS 6 se movimente de forma impressionante, eles ficaram muito felizes com as configurações de cache. Alguém mais viu esse comportamento no iOS 6? Se sim, o que exatamente está causando isso?


A solução alternativa que encontramos foi modificar a assinatura da função para algo como isto:

getNewRecordID(intRecordType, strTimestamp)

e sempre passe também um TimeStampparâmetro e apenas descarte esse valor no lado do servidor. Isso funciona em torno do problema. Espero que isso ajude outra pobre alma que passa 15 horas nessa questão, como eu fiz!


190
Isso é absolutamente chocante. Também passamos algumas horas tentando descobrir o que algo parou de funcionar. Nosso login AJAX que executa um POST (e também possui cabeçalhos para impedir o armazenamento em cache) está sendo armazenado em cache pelo Safari, portanto, ele retorna o mesmo JSON que fez na última vez sem sequer tentar o servidor ... inacreditável! Teremos que hackear uma correção, mas você nunca deve colocar um POST em cache, é uma loucura.
precisa

16
Poste sua solução como uma resposta e não como uma atualização para a pergunta.
ChrisF

50
As solicitações POST são não-idempotentes, o que significa que não devem ser armazenadas em cache , a menos que a resposta o aconselhe especificamente através de seus cabeçalhos de resposta.
James M. Greene

6
Para que a Apple conserte isso, registre um bug em bugreport.apple.com . Eu fiz o mesmo.
Mathias Bynens

11
Mark Nottingham (presidente do grupo IETF HTTPbis de trabalho) escreveu um post interessante sobre isso hoje: mnot.net/blog/2012/09/24/caching_POST
Benjamin Brizzi

Respostas:


447

Após algumas investigações, verifica-se que o Safari no iOS6 armazenará em cache os POSTs que não possuem cabeçalhos de controle de cache ou mesmo "Controle de cache: max-age = 0".

A única maneira que encontrei de impedir que esse cache ocorra em nível global, em vez de precisar hackear seqüências de consultas aleatórias no final das chamadas de serviço, é definir "Cache-Control: no-cache".

Assim:

  • Sem cabeçalhos de controle de cache ou expira = o iOS6 Safari armazenará em cache
  • Idade máxima de controle de cache = 0 e expira imediatamente = iOS6 Safari armazenará em cache
  • Controle de cache: no-cache = iOS6 Safari NÃO armazenará em cache

Suspeito que a Apple esteja tirando proveito disso das especificações HTTP na seção 9.5 sobre o POST:

As respostas a esse método não podem ser armazenadas em cache, a menos que a resposta inclua os campos de cabeçalho Cache-Control ou Expir apropriados. No entanto, a resposta 303 (Consulte Outro) pode ser usada para direcionar o agente do usuário para recuperar um recurso armazenável em cache.

Então, em teoria, você pode armazenar em cache as respostas do POST ... quem sabia. Mas nenhum outro fabricante de navegadores jamais pensou que seria uma boa idéia até agora. Mas isso NÃO leva em consideração o armazenamento em cache quando nenhum cabeçalho Cache-Control ou Expir está definido, apenas quando houver algum conjunto. Portanto, deve ser um bug.

Abaixo está o que eu uso no bit certo da minha configuração do Apache para direcionar toda a minha API porque, como acontece, eu realmente não quero armazenar nada em cache, nem o que é possível. O que eu não sei é como definir isso apenas para POSTs.

Header set Cache-Control "no-cache"

Atualização: observei que não indiquei que é apenas quando o POST é o mesmo; portanto, altere qualquer dado ou URL do POST e você estará bem. Assim, como mencionado em outro lugar, basta adicionar alguns dados aleatórios ao URL ou um pouco de dados POST.

Atualização: Você pode limitar o "sem cache" apenas aos POSTs, se desejar assim no Apache:

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

7
Vejo para onde a Apple está indo com isso, mas estamos vendo respostas em cache a solicitações POST, mesmo quando nossas respostas não incluíram nenhum cabeçalho de controle de cache ou expira. É nesta instância que o iOS6 não deve armazenar em cache e enviar todas as solicitações. Isso não está acontecendo.
Kang_V

138
A parte da especificação HTTP citada não justifica o comportamento de cache do iOS 6. O comportamento padrão deve ser o de não armazenar em cache as respostas do POST (por exemplo, quando o cabeçalho "Cache-Control" não está definido). O comportamento viola as especificações e deve ser considerado um bug. Qualquer pessoa que esteja criando serviços da web xml / json api deve decorar suas respostas do POST com "Cache-control: no-cache" para solucionar esse problema.
David H

39
As solicitações POST são não-idempotentes, o que significa que não devem ser armazenadas em cache , a menos que a resposta o aconselhe especificamente através de seus cabeçalhos de resposta.
James M. Greene

4
Como David diz, é uma clara violação da frase que você citou. Se não houver "Campos de cabeçalho de controle de cache ou expira", obviamente esses cabeçalhos não serão incluídos. No entanto, sua própria investigação mostra que ele está em cache nesse cenário. Edite sua resposta.
Matthew Flaschen

3
Alguém sabe quanto tempo o resultado fica armazenado em cache em um dispositivo? Tentei matar o safari e reiniciar o telefone, mas ele ainda está em cache. Eu sei que ele funciona com a limpeza do cache do navegador, mas estou me perguntando quanto tempo levará para os usuários que já tiveram o problema antes de desaparecer. Nem todo mundo vai pensar em limpar o cache ...
Daniel Hallqvist

146

Espero que isso possa ser útil para outros desenvolvedores batendo a cabeça contra a parede neste. Eu descobri que qualquer um dos seguintes itens impede o Safari no iOS 6 de armazenar em cache a resposta do POST:

  • adicionando [cache-control: no-cache] nos cabeçalhos da solicitação
  • adicionando um parâmetro de URL variável, como o horário atual
  • adicionando [pragma: no-cache] nos cabeçalhos de resposta
  • adicionando [cache-control: no-cache] nos cabeçalhos de resposta

Minha solução foi a seguinte no meu Javascript (todas as minhas solicitações AJAX são POST).

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

Também adiciono o cabeçalho [pragma: no-cache] a muitas das respostas do meu servidor.

Se você usar a solução acima, lembre-se de que todas as chamadas de $ .ajax () feitas como definidas como global: false NÃO usarão as configurações especificadas em $ .ajaxSetup (), portanto, você precisará adicionar os cabeçalhos novamente.


4
Esta é a solução correta para o bug. O problema é que o iOS 6 atenderá solicitações POST de seu cache, em vez de enviá-las ao servidor. O erro não é que ele armazena em cache as respostas das solicitações POST (o que é permitido). Se você ainda deseja obter respostas para solicitações POST recuperadas do cache para solicitações GET subseqüentes a esse URI, use esta solução.
21120 Nicholas Houks

2
Isso funciona para mim, mas não entendo como. Eu já havia especificado cache: false no meu ajaxSetup, e observando os cabeçalhos das solicitações, que se resumem a Cache-Control: no-cache e Pragma: no-cache - mas ele ainda armazenará em cache no iPad. Então, quando adiciono cabeçalhos: {"cache-control": "no-cache"} no ajaxSetup, ele dobra o cabeçalho Cache-Control para "no-cache, no-cache" - e interrompe o cache. O que está acontecendo aqui?
Tom W Salão

Funciona perfeitamente - você também pode adicionar à solicitação como um parâmetro $ .ajax ({type: 'POST', headers: {'cache-control': 'no-cache'}, etc.})
George Filippakos

O que é [pragma: no-cache]? Para que é usada a chave pragma?
zakdances

Eu também acho que essa é a melhor abordagem, em vez de uma solução alternativa com um parâmetro adicional. Nós adicionamos isso apenas nas chamadas onde precisávamos, para chamadas que sempre têm o mesmo retorno, o cache provavelmente é uma coisa boa para o usuário final.
2231313 Germankiwi

67

Solução simples para todas as suas solicitações de serviço da web, supondo que você esteja usando o 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()
    }));
});

Leia mais sobre a chamada do pré-filtro jQuery aqui .

Se você não estiver usando o jQuery, verifique os documentos da sua biblioteca de escolha. Eles podem ter funcionalidade semelhante.


3
Isso não funciona para mim, o servidor responde: "JSON primitivo inválido: timeStamp" asp.net / iis 7.5
Alexandre

3
e o $ .ajax ({"cache": false ...})? funcionará como anexa um _ = [TIMESTAMP]? (Eu faço dispositivo não possuir tal um para testá-lo)
Karussell

Publiquei uma implementação completa da solução proposta por Karussell. Veja minha resposta abaixo.
Sam Shiles 27/09/12

1
@Karussell. Apenas tentei definir $ .ajax ({"cache": false ...}). Isso não resolve o problema de solicitações POST no iOS6. Presumivelmente, porque o JQuery, de acordo com seus documentos, assume que nenhum navegador é estúpido o suficiente para armazenar em cache solicitações de postagem. "As páginas buscadas com POST nunca são armazenadas em cache, portanto, o cache e as opções ifModified em jQuery.ajaxSetup () não têm efeito sobre essas solicitações."
Brett Hannah

1
Isso não funciona. Não mescla parâmetros de postagem. O post de Dave é uma solução melhor.
quer

43

Eu também tive esse problema em um aplicativo PhoneGap . Eu o resolvi usando a função JavaScript getTime()da seguinte maneira:

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

Eu perdi algumas horas descobrindo isso. Seria bom para a Apple notificar os desenvolvedores sobre esse problema de armazenamento em cache.


1
Eu ia comentar sobre o uso {cache:false}como uma opção para um $.post()ou outro $.ajaxSetup(), mas de acordo com a documentação , esses argumentos são ignorados; O jQuery 'nunca armazenará' solicitações de postagem em cache, mas não leva em consideração o navegador. Talvez uma opção melhor seria adicionar um carimbo de data / hora às solicitações usando $.ajaxPrefilter().
precisa saber é o seguinte

i passar quase 5 horas para resolver este problema e, finalmente, acrescentando timestamp irá fazer o truque function send_ajax(my_data,refresh) .. referimos aqui stackoverflow.com/questions/14733772/...
rusly

42

Eu tive o mesmo problema com um aplicativo da Web que obtém dados do serviço da Web do ASP.NET

Isso funcionou para mim:

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

2
Muito obrigado! Eu estava ficando louco tentando descobrir por que o iPhone estava agindo de maneira tão diferente de qualquer outra plataforma. Essa solução específica do ASP.NET me salvou muito tempo.
21812 Mark Brittingham

Não funcionou para em iOS6 ver a minha resposta no final do fio
Brian Ogden

1
Por favor!!!! Coloque uma condição para aplicar isso apenas no IOS 6, o cache de conteúdo é vital para qualquer aplicativo.
Alexandre

24

Finalmente, tenho uma solução para o meu problema de upload.

Em JavaScript:

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

Em PHP :

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

15

No meu próprio post do blog, o iOS 6.0 armazena em cache as solicitações do Ajax POST :

Como corrigir: Existem vários métodos para impedir o cache de solicitações. O método recomendado é adicionar um cabeçalho sem cache. É assim que se faz.

jQuery:

Verifique o iOS 6.0 e defina o cabeçalho do Ajax assim:

$.ajaxSetup({ cache: false });

ZeptoJS:

Verifique o iOS 6.0 e defina o cabeçalho do Ajax assim:

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

Lado do servidor

Java:

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

Adicione isso na parte superior da página antes que qualquer dado seja enviado ao cliente.

.INTERNET

Response.Cache.SetNoStore();

Ou

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.

2
Um bom atributo sem cache para o .NET stackoverflow.com/questions/10011780/… #
43338 Aran Mulholland

7

Este trecho de JavaScript funciona muito bem com o jQuery e o jQuery Mobile:

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

Basta colocá-lo em algum lugar no seu código JavaScript (depois que o jQuery for carregado e o melhor antes de fazer solicitações AJAX) e deve ajudar.


6

Você também pode corrigir esse problema modificando o jQuery Ajax função , fazendo o seguinte (a partir de 1.7.1), na parte superior da função Ajax (a função inicia na linha 7212). Essa alteração ativará o recurso anti-cache interno do jQuery para todas as solicitações POST.

(O script completo está disponível em http://dl.dropbox.com/u/58016866/jquery-1.7.1.js .)

Inserir abaixo da linha 7221:

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

Modifique o seguinte (começando na linha ~ 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 : "");
    }
}

Para:

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

4
Não é uma boa abordagem alterar o jQuery ou qualquer código que você não possua. (Toda vez que você quiser atualizar a versão, precisará fazer a alteração novamente. (Ou outro desenvolvedor é atualizado e o programa não funciona))
andlrc

É uma abordagem perfeitamente válida se você precisar da solução mais rápida possível para atenuar a idiotice da Apple. Essa solução foi usada para resolver o problema de um site massivo que recebe milhões de acessos por dia e nos permitiu fazer isso apenas alterando um arquivo.
Sam Shiles

Você pode ver jQuery.ajaxPrefilerque permite modificar sua solicitação de ajax antes de fazer. Você pode arquivar o mesmo com um código de segurança mais otimizado e atualizado.
andlrc

1
O problema com a abordagem do pré-filtro é que você precisa registrar o filtro. Se você tem um script comum que é executado quando cada página é carregada, tudo bem, mas se não, você teria que configurar o pré-filtro para cada página que usa ajax. No cenário que enfrentamos, tínhamos um local comum para o arquivo JQ que era usado como um recurso para mais de 7 sites individuais. Estávamos perdendo milhares de libras por hora devido a esse bug e a abordagem sugerida nos permitiu resolvê-lo no menor tempo possível, alterando UM arquivo. Eu concordo com você no diretor, mas você tem que ser pragmático às vezes!
Sam Shiles

Você pode adicioná-lo novamente ao final desse arquivo. Que bom que você resolveu, sua empresa deve estar feliz por você.
andlrc

5

Uma solução rápida para os serviços GWT-RPC é adicionar isso a todos os métodos remotos:

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

A maioria de nós possui centenas de métodos remotos em suas implantações de GWT. Existe uma maneira universal de definir o cabeçalho de controle de cache para todas as solicitações?
dirkoneill

5

Esta é uma atualização da resposta de Baz1nga. Como options.datanão é um objeto, mas uma string, apenas recorri à concatenação do carimbo de data e hora:

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

1
Adicionar carimbos de data e hora é uma má ideia, tente a solução de Dave.
Nicholas Shanks

4

Para resolver esse problema dos WebApps adicionados à tela inicial, é necessário seguir as duas soluções alternativas votadas. O armazenamento em cache precisa ser desativado no servidor da web para impedir que novas solicitações sejam armazenadas em cache no futuro e algumas entradas aleatórias precisam ser adicionadas a cada solicitação de postagem para que as solicitações já tenham sido armazenadas em cache. Por favor, consulte o meu post:

iOS6 - Existe uma maneira de limpar solicitações em cache do ajax POST para webapp adicionadas à tela inicial?

AVISO: para quem implementou uma solução alternativa, adicionando um carimbo de data / hora às suas solicitações sem desativar o cache no servidor. Se o seu aplicativo for adicionado à tela inicial, TODAS as respostas pós-publicação serão armazenadas em cache, a limpeza do cache do safari não o limpará e nem parecerá expirar. A menos que alguém tenha uma maneira de limpá-lo, isso parece um possível vazamento de memória!


Todas as respostas serão armazenadas em cache no arquivo ou na memória do telefone?
Eydun

Este não foi o meu caso. Anexei um carimbo de data / hora ao meu URL (não para postar parâmetros) e ele funciona muito bem, tanto ao navegar no safari quanto ao salvar na tela inicial.
ShadeTreeDeveloper

4

Coisas que NÃO FUNCIONARAM para mim com um iPad 4 / iOS 6:

Minha solicitação contendo: Cache-Control: no-cache

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

Adicionando cache: false à minha chamada ajax do jQuery

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

Só isso fez o truque:

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

Para que serve o voto negativo? Isto é importante cache de informações: false não funciona com iPad4 / iOS6 nem //asp.net's: HttpContext.Current.Response.Cache.SetCacheability (HttpCacheability.NoCache)
Brian Ogden

Para a posteridade: a partir de 2017, $.ajax cache: falseanexa a URL ao parâmetro de consulta _=Date.prototype.getTime(), portanto, não é mais necessário anexar manualmente o carimbo de data / hora.
cowbert

3

Essa é a solução alternativa para o 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);    

2

Minha solução alternativa no ASP.NET (métodos de pagem, serviço da web etc.)

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

1

Embora adicionar parâmetros de cache-buster para fazer com que a solicitação pareça diferente pareça uma solução sólida, eu desaconselharia isso, pois prejudicaria qualquer aplicativo que dependa do armazenamento em cache real. Fazer com que as APIs produzam os cabeçalhos corretos é a melhor solução possível, mesmo que seja um pouco mais difícil do que adicionar busters de cache aos chamadores.


1
Embora eu concorde com você na maioria das circunstâncias, eu argumentaria que a solução real para esse problema é a Apple implementar corretamente o HTTP. Com isso em mente, eu não culparia muitos desenvolvedores por implementar a solução mais simples possível até aquele momento. Para mim, modificar a implementação do jquery foi a correção mais simples, pois me permitiu fazer uma edição e ter certeza de que estava ativa em todo o site.
Sam Shiles

1

Para aqueles que usam Struts 1, aqui está como eu corrigi o problema.

web.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

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() {
    }

}

1

Consegui corrigir o meu problema usando uma combinação de $ .ajaxSetup e anexando um carimbo de data / hora ao URL da minha postagem (não aos parâmetros / corpo da postagem). Isso com base nas recomendações de respostas anteriores

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

1

Acho que você já resolveu o problema, mas deixe-me compartilhar uma idéia sobre o cache da web.

É verdade que você pode adicionar muitos cabeçalhos em cada idioma usado, servidor e cliente, além de outros truques para evitar o cache da Web, mas sempre pense que nunca poderá saber de onde o cliente está se conectando ao servidor, você nunca sabe se ele está usando uma conexão “Hot-Spot” de hotel que usa o Squid ou outros produtos de cache.

Se os usuários estão usando o proxy para esconder sua verdadeira posição, etc ... o verdadeiro única maneira de evitar o armazenamento em cache é o carimbo de data / hora na solicitação também se não for usado.

Por exemplo:

/ajax_helper.php?ts=3211321456

Então, todo gerenciador de cache que você precisa passar não encontrou a mesma URL no repositório de cache e voltou a baixar o conteúdo da página.


Resposta antiga, mas meus dois centavos: Esse geralmente é um bom conselho e é entendido pelos desenvolvedores da web mais competentes, mas no caso específico do jQuery, se você criar um $.ajaxe tiver definido as opções {cache:false}, o próprio jQuery adicionará automaticamente um bloqueio de cache nos bastidores, sem precisar fazer mais nada.
JakeGould

0

Dependendo do aplicativo, você pode solucionar o problema agora no iOS 6 usando Safari> Avançado> Inspetor da Web, para que seja útil nessa situação.

Conecte o telefone ao Safari em um Mac e use o menu do desenvolvedor para solucionar o problema do aplicativo da web.

Limpe os dados do site no iPhone após a atualização para o iOS6, incluindo específicos do aplicativo usando um Modo de Exibição na Web. Apenas um aplicativo teve um problema e isso foi resolvido durante o teste do IOS6 Beta, desde então, sem problemas reais.

Pode ser necessário consultar também o seu aplicativo, confira o NSURLCache se estiver em um WebView em um aplicativo personalizado.

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

Eu acho que dependendo da verdadeira natureza do seu problema, implementação, etc.

Ref: chamadas de $ .ajax


Embora isso não atenda diretamente à pergunta original, são informações muito úteis para solucionar problemas em geral nos dispositivos, por isso estou votando positivamente.
Kris Giesing

0

Encontrei uma solução alternativa que me deixa curioso sobre o porquê de funcionar. Antes de ler a resposta de Tadej sobre o serviço Web ASP.NET, eu estava tentando encontrar algo que funcionasse.

E não estou dizendo que é uma boa solução, mas só queria documentá-la aqui.

página principal: inclui uma função JavaScript, checkStatus (). O método chama outro método que usa uma chamada jQuery AJAX para atualizar o conteúdo html. Eu usei setInterval para chamar checkStatus (). Claro, eu tive o problema de armazenamento em cache.

Solução: use outra página para chamar a atualização.

Na página principal, defino uma variável booleana, runUpdate e adicionei o seguinte à tag body:

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

No arquivo helper.html:

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

Portanto, se checkStatus () for chamado na página principal, eu recebo o conteúdo em cache. Se eu chamar checkStatus a partir da página filho, recebo conteúdo atualizado.


0

Enquanto minhas páginas de login e inscrição funcionam como um encanto no Firefox, IE e Chrome ... Eu estive lutando com esse problema no Safari para IOS e OSX, há alguns meses, encontrei uma solução alternativa no SO.

<body onunload="">

OU via javascript

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

Isso é meio feio, mas funciona por um tempo.

Não sei por que, mas, retornando nulo ao onunloadevento, a página não é armazenada em cache no Safari.


0

Descobrimos que iPhones e iPads mais antigos, executando as versões 9 e 10 do iOS, ocasionalmente retornam resultados falsos de AJAX em branco, talvez devido à diminuição da velocidade da CPU da Apple. Ao retornar o resultado em branco, o iOS não chama o servidor, como se estivesse retornando um resultado do cache. A frequência varia amplamente, de aproximadamente 10% a 30% das chamadas AJAX retornam em branco.

A solução é difícil de acreditar. Apenas espere 1s e ligue novamente. Em nossos testes, apenas uma repetição foi tudo o que foi necessário, mas escrevemos o código para chamar até 4 vezes. Não temos certeza se a espera 1s é necessária, mas não queríamos arriscar sobrecarregar nosso servidor com rajadas de chamadas repetidas.

Descobrimos que o problema ocorreu com duas chamadas AJAX diferentes, chamando arquivos de API diferentes com dados diferentes. Mas estou preocupado que isso possa acontecer em qualquer ligação AJAX. Nós simplesmente não sabemos porque não inspecionamos todos os resultados do AJAX e não testamos todas as chamadas várias vezes em dispositivos antigos.

Ambas as chamadas AJAX problemáticas estavam usando: POST, Assíncrona = true, setRequestHeader = ('Content-Type', 'application / x-www-form-urlencoded')

Quando o problema ocorre, geralmente há apenas uma chamada AJAX em andamento. Portanto, não se deve à sobreposição de chamadas AJAX. Às vezes, o problema ocorre quando o dispositivo está ocupado, mas às vezes não, e sem o DevTools, não sabemos realmente o que está acontecendo no momento.

O iOS 13 não faz isso, nem o Chrome nem o Firefox. Não temos dispositivos de teste executando o iOS 11 ou 12. Talvez alguém possa testá-los?

Estou anotando isso aqui porque esta pergunta é o principal resultado do Google ao procurar esse problema.


-1

Ele funcionou com o ASP.NET somente após adicionar o pragma:no-cachecabeçalho no IIS . Cache-Control: no-cachenão foi suficiente.


-2

Sugiro uma solução alternativa para modificar a assinatura da função para algo como isto:

getNewRecordID (intRecordType, strTimestamp) e sempre passe também um parâmetro TimeStamp e apenas descarte esse valor no lado do servidor. Isso funciona em torno do problema.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.