$ .getJSON retornando dados em cache no IE8


102

Estou brincando com ASP.net MVC e JQuery no momento. Eu encontrei um comportamento que não parece fazer sentido.

Estou chamando a $.getJSONfunção JQuery para preencher alguns div's. O evento é acionado no $(document).readyevento. Isso funciona perfeitamente.

Há um pequeno AJAX.BeginFormque adiciona outro valor a ser usado ao preencher os divs. Ele chama a função remota corretamente e, em caso de sucesso, chama a função javascript original para preencher novamente os divs.

Aqui está a parte estranha: no FireFox e no Chrome - tudo funciona. MAS No IE8 (Beta), esta segunda chamada para o script popular Div (que chama a função $ .getJSON) obtém dados em cache e não pergunta ao servidor!

Espero que esta pergunta faça sentido: Em poucas palavras - Por que está $.getJSONobtendo dados em cache? E por que está afetando apenas o IE8?


Estranhamente, vejo esse bug não apenas no IE, mas também no Firefox. Desativar o cache de ajax no jquery me ajudou.
Josef Sábl de

Respostas:


67

Apenas para informá-lo, o Firefox e o Chrome consideram todas as solicitações Ajax como não armazenáveis ​​em cache. O IE (todas as versões) trata a chamada Ajax apenas como outra solicitação da web. É por isso que você vê esse comportamento.
Como forçar o IE a baixar dados em cada solicitação:

  • Como você disse, use a opção 'cache' ou 'nocache' no JQuery
  • Adicione um parâmetro aleatório à solicitação (feio, mas funciona :))
  • No lado do servidor, defina cachability (por exemplo, usando um atributo, veja abaixo)

Código:

public class NoCacheAttribute : ActionFilterAttribute
{
    public override void OnActionExecuted(ActionExecutedContext context)
    {
        context.HttpContext.Response.Cache.SetCacheability(HttpCacheability.NoCache);
    }
}

1
Esta solução me agrada. Eu realmente gosto da elegância de aplicar um atributo em MVC
Andrew Harry

1
Existe um OutputCacheAttribute OOTB hoje em dia.
bzlm

1
@bzlm mas isso é mais fácil de pesquisar
Simon_Weaver

confira formatinternet.wordpress.com/2010/01/14/… para uma solução do lado do cliente
Ivo

1
Na verdade, é o contrário, mas concordo, como um desenvolvedor, o IE requer paciência :)
Nico

107

É assim que funcionou para mim ...

$.ajaxSetup({ cache: false });
$.getJSON("/MyQueryUrl",function(data,item) {
     // do stuff with callback data
     $.ajaxSetup({ cache: true });
   });

Eu estava lutando com esse problema e sua solução me deu uma maneira rápida de resolvê-lo. :) Eu tenho uma pergunta, você sabe quais opções podem ser usadas para $ .ajaxSetup? A documentação do jQuery não fornece detalhes, infelizmente ...
Achimnol

1
As opções disponíveis são idênticas a $ .ajax Consulte docs.jquery.com/Ajax/jQuery.ajax#options para obter mais informações
Dan Esparza

12
Um pequeno aviso para o código acima - contém condição de corrida. Como a chamada e sua resposta são assíncronas, você deve chamar $.ajaxSetup({ cache: true });logo depois de getJSON()e não no retorno de chamada.
sax

16

Obrigado Kent pela sua resposta. Usando $ .ajax ('{cache: no}'); funcionou perfeitamente. [editar]

Ou pelo menos eu pensei que sim. Parece que o jquery $ .getJSON não está lendo nenhuma alteração feita no objeto $ .ajax.

A solução que acabou dando certo foi adicionar um novo parâmetro manualmente

var noCache = Date();
$.getJSON("/somepage/someaction", { "noCache": noCache }, Callback);

a resolução de data é minuciosa; o que efetivamente significa que essa solução ainda armazena em cache por até um minuto. Isso é aceitável para meus propósitos.


9
var noCache = new Date (). getTime (); // lhe dará o ms
scunliffe

obrigado Scunliffe! - eu sou muito novo em javascript, ASP MVC abriu novos horizontes para mim
Andrew Harry

Você também pode tentar algo como Math.Random ().
Falkayn,

@Falkayn - tough Math.Random()pode ser usado, seus resultados serão desconhecidos e você pode obter o mesmo número duas vezes seguidas (ou mais). o uso new Date().getTime()garantirá que nunca seja repetido. (a menos que você seja capaz de voltar no tempo;))
Demência

11

Resolvi esse mesmo problema colocando o seguinte atributo na Ação no Controlador:

[OutputCache(Duration = 0, VaryByParam = "None")]

Maravilhoso! Ótimo ter alternativas (eu escolhi esta). Obrigado a todos os contribuidores!
Anders Juul

Funciona bem com Asp.Net MVC 4.0
Mayank

4

Se você estiver usando ASP.net MVC, considere adicionar um método de extensão para implementar facilmente nenhum armazenamento em cache, como:

    public static void NoCache(this HttpResponse Response)
    {
        Response.Cache.SetNoStore();
        Response.Cache.SetExpires(DateTime.MinValue);
        Response.Cache.SetCacheability(HttpCacheability.NoCache);
        Response.Cache.SetValidUntilExpires(false);

        Response.Expires = -1;
        Response.ExpiresAbsolute = DateTime.MinValue;
        Response.AddHeader("Cache-Control", "no-cache");
        Response.AddHeader("Pragma", "no-cache");
    }

Boa ideia - então você chama esse método de extensão no servidor durante o retorno de chamada, certo?
Guy

2

Pode ser necessário enviar um quebrador de cache.

Eu recomendaria usar $ .ajax ({cache: no}) apenas no caso (adiciona um sufixo aleatório à solicitação get)

(Eu costumo usar $ .ajax em todos os lugares hoje em dia, mais ajustável)


Obrigado pela sua resposta! ... ainda não experimentei. Fornecerá feedback em breve
Andrew Harry

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.