Usamos cookies para medir audiência e melhorar sua experiência. Você pode aceitar ou recusar a qualquer momento. Veja sobre o iMasters.
Salve iMasters.
Bom, trago hoje uma criação que pode ajudar em muito que está começando no mundo AJAX.
Vejo por aí que muitos de vocês fazem uso de jQuery APENAS para utilização de AJAX. Os frameworks estão aí, vieram pra ficar, são uma mão-na-roda e ajudam muito!!! Desde que você saiba o que está fazendo! Muita gente baixa as bibliotecas, enche o sistema de plug-ins e, quando vai ter que dar manutenção, se perde todo na quantidade de informações de terceiros agregadas ao sistema!
Para projetos de grande porte, existe ainda outro problema: custo de dados. Incorporar todos os 25Kb (55 se o seu servidor não suportar gzip) por causa de um recurso é coisa de amador! Os 155Kb da biblioteca descomprimida então, nem pensar!!
O objeto XMLHttpRequest é uma standard, prevista pela W3C que pode, E DEVE ser utilizado de forma independente.
O grande problema é que, devido à disparidade entre os navegadores (e vocês pensando que isso só acontecia com CSS), alguns métodos e eventos previstos para um - navegador - pode não estar presente em outro(s).
O Objeto AJAX inteligente surge para preencher esta lacuna entre um objeto XMLHttp cru e uma framework inteira subutilizada.
Conteúdo obsoleto foi escondido
Sem mais blá-blá-blá, a definição:
/**
* Creates an Ajax Class.
* @author Evandro Oliveira <evandrofranco[at]gmail[dot]com>
* @version 0.2.3 [2010-09-10 11:34 GMT-0300]
*
* @param {Callback} noAjax A function to be run if XMLHttp object cannot
* be created.
*
* @return a new Ajax object
*/
var Ajax = function(noAjax){
// Verifying XMLHttp support
if(!window.XMLHttpRequest) return noAjax();
else {
var xhr = new XMLHttpRequest();
if(xhr == null) return noAjax();
}
// Config database
var params = new Object();
params.url = 'about:blank';
params.method = 'GET';
params.async = true;
params.timeout = 30000;
params.response = false;
params.onabort = function(){};
params.oncomplete = function(){};
params.onerror = function(){};
params.ontimeout = function(){};
params.onupdate = function(){};
params.headers = new Array();
/**
* This function defines a new URL to be run with Ajax object.
* @param {String} newUrl The new URL to run.
* @return Itself.
*/
this.setUrl = function(newUrl){
if(newUrl != undefined) params.url = newUrl;
return this;
};
/**
* This function defines the request method.
* @param {String} newMethod The new request method.
* @return Itself.
*/
this.setMethod = function(newMethod) {
if(newMethod != undefined) params.method = newMethod;
return this;
};
/**
* This function defines whether the request'll be asynchronous.
* @param {Boolean} value The async switch.
* @return Itself;
*/
this.setSync = function(value) {
if(value != undefined) params.async = (value != false);
return this;
};
/**
* Defines the max execution time for each request.
* This function was originallly created for MSIE8 and
* this Ajax object emulates the behavior in all major
* browsers.
* @param {Number} newTimeout The max execution time in miliseconds.
*/
this.setTimeout = function(newTimeout) {
if(newTimeout != undefined) params.timeout = newTimeout;
return this;
};
/**
* Defines the return mode.
* Switch between XML data (true) or Text data (false).
* @param {Boolean} mode The response mode.
* To get an XML response, set it to true. False swith
* gets a pure-text response.
* @return Itself.
*/
this.setXmlReturn = function(mode) {
if(mode != undefined) params.response = (mode != false);
return this;
};
/**
* Adds events listener callbacks. Actions to be executed
* at [Abort, Complete, Error, Update and Timeout] cases.
* @param {String} event The case listener.
* @param {Callback} callback The action to be taken.
*/
this.setEvent = function(event, callback){
switch(event){
case 'complete': params.oncomplete = callback; break;
case 'timeout': params.ontimeout = callback; break;
case 'update': params.onupdate = callback; break;
case 'abort': params.onabort = callback; break;
case 'error': params.onerror = callback; break;
}
};
/**
* Adds or edit the headers table.
* @param {String} name The header name.
* @param {String} value The header value.
*/
this.setHeader = function(name, value){
if(name == undefined || value == undefined) return;
for (var i = 0, ln = params.headers.length; i < ln; i++)
if (params.headers[i].name = name) {
params.headers[i].value = value;
return;
}
var newHeader = new Object();
newHeader.name = name;
newHeader.value = value;
params.headers.push(newHeader);
};
/**
* Adds access to the XMLHttp.abort() method. Also calls
* the abort event listener callback.
*/
this.abort = function(){
xhr.abort();
params.onabort();
};
/**
* Starts the request.
* - Prepare the XMLHttp object
* - Set the headers
* - Set the listeners
* - Prepare data
* - Send data
* - Call respective listeners
* @param {Object} data The data to be send.
*/
this.send = function(data){
var newData = new Array();
for(var i in data) newData.push(i + '=' + data[i]);
data = newData.join('&');
if(params.method == 'GET') params.url += '?' + data;
xhr.open(params.method, params.url, params.async);
xhr.onreadystatechange = function(){
params.onupdate(xhr.readyState);
if(xhr.readyState == 4){
clearTimeout(myTimeout);
if(xhr.status == 200)
params.oncomplete((params.response)? xhr.responseXML : xhr.responseText);
else params.onerror(xhr.status, xhr.statusText);
}
};
for(var i = 0, ln = params.headers.length; i < ln; i++)
xhr.setRequestHeader(params.headers[i].name, params.headers[i].value);
xhr.send(data);
var myTimeout = setTimeout(function(){
xhr.abort();
params.ontimeout();
}, params.timeout);
};
this.setHeader('content-type', 'application/x-www-form-urlencoded');
this.setHeader('HTTP_X_REQUESTED_WITH', 'XMLHttpRequest');
};
Trata-se de uma classe (orientação a objetos).
Para descrição de métodos e utilização, citarei exemplos conseguintes, unindo-os, ao final, temos um sistema em funcionamento.
Primeiro, criamos a página que recebe as requisições:
ajax.txt
requisição ajax funcionou!
Agora vamos criar um novo objeto da classe Ajax
var xmlhttp = new Ajax();
O método construtor nos permite passar à classe, em forma de parâmetro, uma função (callback) que será executada caso não seja possível criar um novo objeto AJAX.
Podemos, por exemplo, enviar um alerta ao usuário
var xmlhttp = new Ajax(function(){ alert('Não foi possível criar o objeto AJAX!') });Teste no IE6 ;)
Como somos programadores inteligentes, vamos utilizar isso a nosso favor, vamos definir uma variável global que nos indica se temos ou não suporte a AJAX.
var hasAjax = true;
var xmlhttp = new Ajax(function(){ hasAjax = false; });
if(!hasAjax) alert('Ajax indisponível');
Pronto! Temos uma criação segura do objeto e ainda temos como verificar se existe ou não suporte à tecnologia. Vamos agora, configurar o objeto.
Em objetos XMLHttpRequest padrão, temos o método open() para definir o método de transação de dados, a url a ser acessada e se o acesso será ou não assíncrono.
Para o objeto Ajax, temos métodos em separado para cada atributo.
método
xmlhttp.setMethod('GET');O método get já é definido por padrão, não sendo necessário fazer essa atribuição.
url
xmlhttp.setUrl('http://forum.imasters.com.br');
sincronia
xmlhttp.setSync(true);
Atenção: Este método define se a requisição será assíncrona, o que pode causar uma certa confusão na hora de definir o seu valor. Por padrão, o valor é dado como true o que indica que o usuário continuará livre para navegar enquanto a requisição XMLHttp estiver sendo processada (comportamento padrão).
Algumas novas propriedades são adicionadas ao objeto Ajax. São elas: XmlReturn e Timeout
xmlReturn define se o valor retornado pelo objeto Ajax ao concluir a requisição será em formato xml ou texto.
xmlhttp.setXmlReturn(false);True: retorna em XML. False(padrão): Retorna em texto.
timeout define o tempo que o objeto deverá aguardar até o término da requisição (em milisegundos).
xmlhttp.setTimeout(10000);Aguardando 10 segundos...Nota: Se o tempo de timeout do objeto Ajax for maior que o tempo de timeout do servidor, o objeto Ajax encerrará com o evento onerror enviando como parâmetro o código de erro 504 - Gateway Time Out.
Após isso, é necessário definir o comportamento do controlador em determinados eventos. Por exemplo, para descobrir se a requisição está terminada, no objeto XMLHttp, temos que verificar no evento readystatechange o status do objeto. Tudo isso é gerenciado pelo objeto Ajax, cabendo ao desenvolvedor apenas atrelar as funções a cada um dos seguintes eventos:
abortagem - quando a requisição é cancelada antes de se completar e antes do timeout expirar.
xmlhttp.setEvent('abort', function(){});Este callback não recebe parâmetros.
atualização - cada vez que o objeto XMLHttp muda de estado
xmlhttp.setEvent('update', function(){});Por padrão, o callback recebe o valor da propriedade readyState do objeto XMLHttp.
conclusão - ao terminar a requisição com sucesso
xmlhttp.setEvent('complete', function(){});Os dados passados por parâmetro ao callback é a resposta xmlhttp.responseText ou xmlhttp.responseXml conforme definido pelo método xmlhttp.setXmlReturn.
erro - ao terminar a requisição sem sucesso
xmlhttp.setEvent('error', function(){});Este *callback* recebe dois parâmetros: - O código de erro HTTP
- A descrição do erro
tempo esgotado - quando se expira o timeout do objeto Ajax.
xmlhttp.setEvent('timeout', function(){});Este callback não recebe parâmetros.
Brinde! Cabeçalhos:
Podemos enviar junto com a requisição, cabeçalhos que indicam o tipo de requisição que estamos fazendo e que tipo de dados esperamos de volta
xmlhttp.setHeader('content-type', 'application/x-www-form-urlencoded');
Pronto! Nosso objeto Ajax está configurado e pronto para rodar. Mas como rodamos?
Através do método send(), como no objeto XMLHttp, com uma nova facilidade: Independente do método de requisição, os dados de envio podem ser passados como parâmetro para send() em forma de objeto. A conversão será transparente e funcional.
Método antigo
xmlhttp.open('GET', 'pagina.php?nome=Evandro&idade=21');
Novo método
xmlhttp.setUrl('pagina.php');
xmlhttp.send({nome: "Evandro"; idade: 21;});
Para terminar, para a galera que já está acostumada com jQuery, é possível configurar vários parâmetros ao mesmo tempo de uma vez:
xmlhttp.setMethod('GET').setUrl('pagina.php').setSync(true);
Lembra do nosso arquivo ajax.txt lá do começo? Bom então agora vamos juntar todas as informações que aprendemos e criar um sistema de MOTD(Message of the day - mensagem do dia) para o nosso site!
HTML - criando um contêiner para o MOTD
<div id="motd"></div>
Javascript
var hasAjax = true;
var xhr = new Ajax(function(){ hasAjax = false; });
if(hasAjax) {
xhr.setUrl('ajax.txt').setEvent('complete', function(message){
document.getElementById('motd').innerHTML = message;
}).setEvent('update', function(){
document.getElementById('motd').innerHTML = 'Aguarde, recuperando mensagem...';
}).send();
}
Link para a documentação mais atual
Bônus Lá no começo, disse que poderia testar o que acontece caso não haja suporte a AJAX no IE6. Mas você pode querer que este fadado navegador também funcione com o seu sistema, sei lá os seus motivos. Para isso, basta criar a classe XMLHttpRequest
/**
* Adds the standard XMLHttpRequest class to IE6.
* @author Evandro Oliveira <evandrofranco[at]gmail[dot]com>
*
* @version 0.1 [2010-09-10 10:37 GMT-0300]
*
* @return A new XMLHTTP object if supported, else NULL.
*/
if(!window.XMLHttpRequest) var XMLHttpRequest = function(){
var tryes = new Array("MSXML2.XMLHTTP.7.0", "MSXML2.XMLHTTP.6.0", "MSXML2.XMLHTTP.5.0", "MSXML2.XMLHTTP.4.0", "MSXML2.XMLHTTP.3.0", "MSXML2.XMLHTTP", "Microsoft.XMLHTTP");
var XMLHttp = null;
while(XMLHttp == null && tryes.length > 0)
try { XMLHttp = new ActiveXObject(tryes.shift()); }
catch(e){};
return XMLHttp;
}
Vale lembrar que este suporte deve ser carregado ANTES de instanciar um novo objeto Ajax.
ajax.js
ajax-min.js
Suporte ao IE 6
ie6ajax.js
ie6ajax-min.js
Aguardo dúvidas, feedback e opiniões. Espero que gostem!
Carregando comentários...