Desde a atualização para o iOS 6, estamos vendo a visualização na Web do Safari ter a liberdade de fazer cache de $.ajax
chamadas. Isso ocorre no contexto de um aplicativo PhoneGap e, portanto, ele usa o Safari WebView. Nossas $.ajax
chamadas são POST
métodos e temos cache definido como false {cache:false}
, mas ainda está acontecendo. Tentamos adicionar manualmente um TimeStamp
aos 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 TimeStamp
parâ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!
fonte
Respostas:
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:
Suspeito que a Apple esteja tirando proveito disso das especificações HTTP na seção 9.5 sobre o POST:
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.
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:
fonte
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:
Minha solução foi a seguinte no meu Javascript (todas as minhas solicitações AJAX são POST).
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.
fonte
Solução simples para todas as suas solicitações de serviço da web, supondo que você esteja usando o jQuery:
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.
fonte
Eu também tive esse problema em um aplicativo PhoneGap . Eu o resolvi usando a função JavaScript
getTime()
da seguinte maneira:Eu perdi algumas horas descobrindo isso. Seria bom para a Apple notificar os desenvolvedores sobre esse problema de armazenamento em cache.
fonte
{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()
.function send_ajax(my_data,refresh)
.. referimos aqui stackoverflow.com/questions/14733772/...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:
fonte
Finalmente, tenho uma solução para o meu problema de upload.
Em JavaScript:
Em PHP :
fonte
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:
ZeptoJS:
Verifique o iOS 6.0 e defina o cabeçalho do Ajax assim:
Lado do servidor
Java:
Adicione isso na parte superior da página antes que qualquer dado seja enviado ao cliente.
.INTERNET
Ou
PHP
fonte
Este trecho de JavaScript funciona muito bem com o jQuery e o jQuery Mobile:
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.
fonte
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:
Modifique o seguinte (começando na linha ~ 7497).
Para:
fonte
jQuery.ajaxPrefiler
que 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.Uma solução rápida para os serviços GWT-RPC é adicionar isso a todos os métodos remotos:
fonte
Esta é uma atualização da resposta de Baz1nga. Como
options.data
não é um objeto, mas uma string, apenas recorri à concatenação do carimbo de data e hora:fonte
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!
fonte
Coisas que NÃO FUNCIONARAM para mim com um iPad 4 / iOS 6:
Minha solicitação contendo: Cache-Control: no-cache
Adicionando cache: false à minha chamada ajax do jQuery
Só isso fez o truque:
fonte
$.ajax
cache: false
anexa a URL ao parâmetro de consulta_=Date.prototype.getTime()
, portanto, não é mais necessário anexar manualmente o carimbo de data / hora.Essa é a solução alternativa para o GWT-RPC
fonte
Minha solução alternativa no ASP.NET (métodos de pagem, serviço da web etc.)
fonte
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.
fonte
Para aqueles que usam
Struts 1
, aqui está como eu corrigi o problema.web.xml
com.example.struts.filters.CacheControlFilter.js
fonte
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
fonte
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:
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.
fonte
$.ajax
e tiver definido as opções{cache:false}
, o próprio jQuery adicionará automaticamente um bloqueio de cache nos bastidores, sem precisar fazer mais nada.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
fonte
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:
No arquivo helper.html:
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.
fonte
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.
OU via javascript
Isso é meio feio, mas funciona por um tempo.
Não sei por que, mas, retornando nulo ao
onunload
evento, a página não é armazenada em cache no Safari.fonte
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.
fonte
Ele funcionou com o ASP.NET somente após adicionar o
pragma:no-cache
cabeçalho no IIS .Cache-Control: no-cache
não foi suficiente.fonte
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.
fonte