quinta-feira, abril 10, 2008

Simulando Ajax em browsers sem Ajax

É possível implementar Ajax sem utilizar Microsoft.XMLHTTP, Msxml2.XMLHTTP ou XMLHttpRequest (o título deste artigo é apenas para polemizar). Se você tiver que implementar sites que funcionem em IEs antigos (5.55 em windows antigos), esse artigo pode lhe interessar. Uma possível solução é:

  1. Criar um iframe dinamicamente
  2. Criar um form dentro deste iframe
  3. Preencher um campo deste form com os dados a serem enviados
  4. Dar submit no form
  5. Fazer um "loop" com setTimeout para verificar quando os dados voltaram do servidor.
Segue abaixo alguns exemplos de como fazer isso.

Criar iframe dinamicamente:
document.body.innerHTML += '<iframe name="meuframe"> </iframe>;

ou (solução menos bugada)

var f = document.createElement("iframe");
f.setAttribute("name", "meuframe");
document.body.appendChild(f);
Deixar o iframe invisível:
// Aplique o seguinte estilo no iframe
visiblility:hidden; // com display:none não funfa no FF
width:0px; height:0px; // para ele não ocupar espaço
border:0px; // se ficar com a borda, o FF exibe um bloquinho cinza
Criar form no iframe e preencher campo:
var html = '';
html += '<form name="meuform" method="post" action="minhaurl" >';
html += '
<textarea name="dados">' +mensagem + '</textarea >';
html += '</form>';
// NÃO use document.body.innerHTML, pois o FF não conseguirá dar submit()!
frames['meuframe'].document.write(html);

Dar submit no form:
frames['meuframe'].document.forms[0].submit();
Loop que aguarda retorno dos dados:
function etapa4 () {
// se ainda houver um form é o pq os dados ainda não chegaram
if (frames['meuframe'].document.forms.length == 1) {
window.setTimeout("etapa4()", 100);
return;
} else {
var r =
frames['meuframe'].document.body.innerHTML;
eval("meucallback(" + r + ");");
}
}

Esta solução verifica a cada 1/10 de segundo se os dados voltaram do servidor. Assim que os dados voltarem, a função meucallback() é chamada, sendo passado como parâmetro o resultado.

Obs importante:
É preciso dar um intervalo de tempo entre as etapas para que o navegador "perceba" os novos objetos. Para isso, acrescente no final de cada função (cada etapa deve estar em uma função diferente) um temporizador:
// ex de código a ser colocado no final da etapa2
window.setTimeout("chama_etapa_3()", 10);


Solução Testada em:
  • Windows XP (SP2)
  • FF: Firefox 2.0.0.7
  • IE: Internet Explorer 7 e Internet Explorer 5.55
Deixe um comentário!
:)

Um comentário:

  1. nao conte para ninguem, mas o site da maior empresa de aviacao do brasil eh feito neste esquema...

    []s..............................izraeu

    ResponderExcluir