13 de jan de 2009

Desativando o cache de SWF do navegador

Precisei dessa dica outro dia, procurei feito doido e achei algumas coisas, esta aqui foi a que melhor resolveu meu problema, então estou traduzindo-a:
Durante o desenvolvimento Flash provavelmente você perceberá que ao testar seu SWF no navegador a versão antiga permanecerá mesmo você tendo feito alterações no arquivo e acabado de reenvia-lo ao servidor. Isso acontece porque o nosso querido navegador (seja ele qual for) não percebe que o arquivo foi alterado.

Desativar o cache do seu navegador só irá resolver o problema pra você, mas e o resto dos internautas? Com certeza eles não irão querer fazer isso, por mais que você peça. Felizmente há maneiras de impedir que o navegador guarde o arquivo no cache, então vejamos algumas:

1- Crie um arquivo PHP pra chamar o SWF separado do resto do site:

<?php
header('Content-type: application/x-shockwave-flash');
header('Expires: Thu, 01 Jan 1970 00:00:00 GMT, -1');
header('Cache-Control: no-cache, no-store, must-revalidate');
header('Pragma: no-cache');
echo file_get_contents('arquivo.swf');
?>

Este PHP irá servir como um mediador entre as requisições do navegador e o servidor. O navegador continuará pensando que o arquivo é uma requisição de arquivo SWF, mas o servidor dirá ao navegador que ele não poderá guardar o arquivo no cache, legal né?

2- O que você tem que fazer agora é chamar o PHP ao invés do SWF na sua página, que pode até ser um html comum:

<object width="640" height="480" align="middle">
<param name="movie" value="seuarquivo.php" />
<param name="bgcolor" value="#000000" />
<embed src="seuarquivo.php" width="640" height="480" scale="noscale" bgcolor="#000000"
type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" />
</object>

Pronto! Agora você tem um arquivo SWF que se recarrega a cada nova requisição! Agora o mesmo problema tende a acontecer dentro do Flash quando você usa URLRequest, então você imagina que o AC abaixo possa resolver a sua vida:

var loader:URLLoader = new URLLoader();
var request:URLRequest = new URLRequest(whatever url);
request.requestHeaders.push(new URLRequestHeader("pragma", "no-cache"));
request.requestHeaders.push(new URLRequestHeader("Expires", "Thu, 01 Jan 1970 00:00:00 GMT, -1"));
request.requestHeaders.push(new URLRequestHeader("Cache-Control", "no-cache, no-store, must-revalidate"));
loader.load(request);

Pro seu azar isso não funciona! Por alguma razão obscura, o Flash não respeita qualquer regra de cache. A saída é apelar pro famoso "jeitinho brasileiro" fazendo o flash "pensar" que cada url é nova a cada requisição:

var request:URLRequest = new URLRequest("whateverurl?nocache=" + new Date().getTime());

Infelizmente (de novo?!) este método também tem uma disvantagem: se você estiver usando URLVariables, vai dar conflito! A solução é simplesmente usar a URLVariable com o macete anti-cache:

var request:URLRequest = new URLRequest(whateverurl);
var variables:URLVariables = new URLVariables();
variables.nocache = new Date().getTime();
// configure outras URLVariables aqui
request.data = variables;

Aleluia! Finalmente o cache do flash tá desligado! Espero que esta dica seja útil a alguém. Lemre-se: A primeira dica é suficiente pra maioria que tenha feito um SWF simples, mas quem usa URLRequest e URLVariables vai precisar do pacote completo.

Pra quem quiser ver o artigo original basta clicar aqui.

2 comentários:

ismarview disse...

Olá, sobre esse problema do cache de SWF, eu não estou entendendo direito onde colocar esses códigos dentro do Flahs.
Estou usando o comando (loadMovieNum), nesse caso se eu fechar a página e entrar novamente o cache do primeiro SWF eu consigo atualizar usando um código dentro do HTML mas e dentro do flash que está chando outro flahs, o que eu preciso fazer para que seja atualizado sempre, pois um ama vez clicado no link ele carregou uma vez o segundo swf e aí se eu clicar novamente ele continua mostrando o mesmo SWF.

Obrigado,
Ismar

[k]Élida disse...

Bem, estou com o mesmo problema do POST acima. Não entendo exatamente onde colocar estas variaveis.

Uso (LoadMovie)...
Teria como detalhar melhor esta explicação.

obraigada.