Google Suggest: Não é Ajax
Maio 28, 2009
Como assim? Mas eu digito uma letra e aparece uma janelinha me dando sugestões em tempo de digitação!
Pois é, o Google Suggest utiliza sim requisições assíncronas mas não podemos chamar de Ajax.
O famoso Ajax ficou conhecido devido ao uso do objeto XMLHttpRequest e o nosso amigo Google não utiliza este objeto para fazer suas requisições assíncronas, ele utiliza simplesmente o fato de chamar scripts externos.
Essa é uma técnica antiga muito utilizada quando o XMLHttpRequest não era tão famoso, o pessoal já se virava com seus scripts dinâmicos e iframes.
Como funciona internamente o Google Suggest?
Na primeira letra digitada ele faz a criação dinâmica de uma tag <script> já setando seu atributo src para http://clients1.google.com.br/complete/search?hl=pt-BR&q= sendo que o parâmetro q equivale ao valor do campo de busca.
Então por exemplo, vou buscar sobre “futebol”, assim que digito a letra “f”, ele faz todo esse processo apontando para http://clients1.google.com.br/complete/search?hl=pt-BR&q=f
Na segunda letra digitada, visto que a tag <script> já foi criada anteriormente ele simplesmente muda o atributo src agora apontando para a nova url http://clients1.google.com.br/complete/search?hl=pt-BR&q=fu
Mas como através dessa requisição aparece a lista de sugestões ?
A resposta dessa requisição é simplesmente texto puro, mas por ser chamada na tag <script> ela acaba sendo reconhecida como JavaScript e sendo executada por quem a chamou, em nosso caso a página inicial do Google.
O retorno da requisição é simplesmente isso (Um exemplo para a busca da palavra fut):
window.google.ac.h(["fut",[["futebol ao vivo","5.880.000 resultados","0"], ["futebol","39.800.000 resultados","1"]
Somente essa linha de código é responsável por popular a lista de sugestões.
Segue abaixo uma screenshot no momento da “popularização” de dados:
Por que a Google não utilizou o XMLHttpRequest? Isso foi uma boa solução?
Não é interessante para o Google Suggest controlar o retorno da requisição, saber readyState, status, nada disso é interessante visto que uma requisição é feita a cada letra digitada, então cada requisição sobrescreve a outra.
Não estamos preocupados se a requisição foi feita corretamente, ele simplesmente faz a requisição e se concluir OK, se não der tempo de completar (Isso é bem provável pois se outra letra foi digitada uma nova requisição foi feita), então ele esquece a chamada anterior e vai para a próxima, assim até o usuário “descansar” o dedo e dar tempo para a requisição ser concluída, logo depois a conclusão será mostrado para o usuário os resultados de sua busca.
Outro ponto interessante é a compatibilidade entre browsers. Navegadores muito antigos não têm suporte a XMLHttpRequest e atuais como o IE podem desabilitar essa opção, então na minha opinião foi uma ótima sacada sendo que é garantido que rodará em praticamente qualquer navegador.
Ajax: Classe para múltiplas requisições assíncronas
Maio 26, 2009
Ainda vejo muitos desenvolvedores tentando fazer duas requisições Ajax ao mesmo tempo e sofrendo muito com os problemas que isso pode causar. Lembrando que ao fazer a segunda requisição (junto com a primeira) você está simplesmente anulando a anterior. Outra opção é a criação de diversas instâncias de XMLHttpRequest, mas também não é viável devido a incompatibilidade e sobrecarregamento do browser.
Recentemente desenvolvi uma classe Ajax que suporta múltiplas requisições utilizando o conceito de fila e venho aqui compartilhar com vocês.
É uma classe simples responsável por encapsular toda a complexidade do Ajax (não que Ajax seja difícil, pelo contrário Ajax é muito fácil desde que seja utilizado corretamente).
Utilizando o padrão Singleton (lembrando que esse padrão não é 100% seguro em JavaScript) criamos uma única instância do objeto XMLHttpRequest para ser usado em todas as requisições.
Código de classe:
Clique aqui para ver
Modo de usar:
1 Ajax.doPost(“teste.php“, “param=1¶m=2″, function()
2 {
3 if (Ajax.getInstance().readyState == 4)
4 {
5 if (Ajax.getInstance().status == 200)
6 {
7 alert(Ajax.getInstance().responseText);
8 }
9 Ajax.next();
10 }
11 });
Código de exemplo:
Clique aqui para ver
Basta chamar o método Ajax.doPost() para executar uma nova requisição sem se importar se a requisição anterior foi concluída ou não, pois o próximo doPost() somente será executado se a requisição anterior foi concluída.
