Ir para conteúdo
Fórum Script Brasil
  • 0

Classe AJAX


Jonathan Queiroz

Pergunta

Para facilitar a utilização de AJAX em alguns sites que estava desenvolvendo resolvi criar uma classe. Conforme pedido de membro, postarei essa classe aqui.

Embora o código da classe seja auto-explicativo, postarei uma breve explicação:

Para evitar problemas quando o navegador não possui suporte a AJAX, o uso da classe (cujo nome, por falta de criatividade do autor motivos desconhecidos, é AjaxClass) só ficará habilitado se o navegador suportar AJAX. Sendo assim, antes de utilizar a classe verifique se ela existe. Isso pode ser feito da seguinte forma:

if(AjaxClass){
alert("tem suporte AJAX !!!")
//...cria a requisição...
}else{
alert("Não há suporte a AJAX")
}
O AjaxClass traz uma classe interna (AjaxClass.RequestValue) que pode ser utilizada para passar parâmetros à página que será requisitada (seja por POST ou GET). Basta instanciar a classe, manipular os valores (métodos setValue, getValue e remove) e passar essa subclasse como um dos parâmetros do método add (explicarei depois). Exemplo:
//...
var valores = new AjaxClass.RequestValue()
valores.setValue("valor1","bom dia")
valores.setValue("tarde","boa tarde")
valores.setValue("outro_valor","boa noite")
valores.remove("tarde")
alert(valores.getValue("valor1")) // bom dia
alert(valores.getValue("tarde")) // null
alert(valores.getValue("outro_valor")) // boa noite
Para adicionar uma requisição, basta utilizar o método add do AjaxClass. O protótipo da função é:
function(
metodo, //Método da requisição. "GET" ou "POST"
url, //Url da página que será requisitada. Ex.: "pagina1.php"
valores, //Objeto da classe "RequestValue". Também pode ser null (nesse caso, nenhum valor é utilizado)
funcao_sucesso, /*Função chamada quando há
 sucesso (o primeiro parâmetro é o resultado da requisição)*/
funcao_erro /*Função chamada quando ocorre algum erro.
Se for passado o valor booleano "true", a função "funcao_sucesso" será
chamada (mas o primeiro parâmetro será "null" ao invés de ser o retorno da requisição)*/
)
Para os exemplos de utilização criei quatro arquivos (dos quais somente três são necessários)
  • AjaxClass.js (código responsável pela nossa classe);
  • pagina.html (página que utiliza a classe);
  • arquivo.asp (script simples em ASP que mostra os valores passados por GET/POST)
  • arquivo.php (script simples em PHP 5 que mostra os valores passados por GET/POST)
Obs.:
  1. Lembrem-se de salvar os arquivos arquivo.asp e arquivo.php em UTF-8 (na dúvida, abra o bloco de notas, vá em Salvar como, coloque a codificação como UTF-8 e clique em Salvar). Isso deve ser utilizado para qualquer arquivo que venha a ser requisitado por AJAX. Isso pode ser feito nas opções de seu editor.
  2. Criei os arquivos em PHP e ASP apenas para facilitar o entendimento de quem ler (se fizesse em apenas uma linguagem, quem não tivesse experiência nela teria mais dificuldade em entender o código). No arquivo de utilização (pagina.html), o arquivo arquivo.php é requisitado, mas isso pode ser alterado facilmente (basta trocar o ".php" para ".asp" na linha 20). Também é possível alterar o método de POST para GET (o que também irá modificar o resultado da requisição), basta trocar o POST para GET na linha 19.
AjaxClass.js
/******** Classe AJAX ********
Autor: Jonathan Coutinho Luz de Queiroz
E-mail: jonathan.jclq@gmail.com
*/
AjaxClass = function () {
    /*Criar requisição AJAX*/
    this.CreateXMLHttpRequest = function () {
        try {
            // Firefox, Opera 8.0+, Safari, IE7+, ...
            return new XMLHttpRequest();
        } catch (e) {
            // Internet Explorer 6+
            try {
                return new ActiveXObject("Msxml2.XMLHTTP");
            } catch (e) {
                //Internet Explorer 5.5+
                try {
                    return new ActiveXObject("Microsoft.XMLHTTP");
                } catch (e) {
                    //Não conseguiu criar o objeto
                    return null;
                }
            }
        }
        return xmlHttp
    }
    //Objeto XMLHTTP
    var xmlhttp = this.CreateXMLHttpRequest()
    //Verificamos se a requisição foi instancia com sucesso
    if (!xmlhttp) {
        /*Não conseguimos instanciar o XMLHTTP.
        Nesse caso, o objeto AJAX será "null"*/
        return null
    }
    //Requisições
    var atual
    var requisicoes = []
    var processando
    if (!atual) {
        atual = 0
    }
    //Valores para requisição
    this.RequestValue = function () {
        //Variáveis
        var itens = []
        //adicionar/Modificar
        this.setValue = function (nome, valor) {
            try {
                valor = valor.toString()
            } catch (e) {
                valor = ""
            }
            itens[nome] = valor
        }
        //Remover
        this.remove = function (nome) {
            itens[nome] = null
        }
        //Obter valor
        this.getValue = function (nome) {
            return itens[nome]
        }
        //Obter string
        this.getString = function () {
            //Retorno dessa função
            var retorno = ""
            //Codificação (tratamento de string)
            var encode = function (v) {
                return v
                    .toString()
                    .replace(/&/g, "%26")
                    .replace(/ /g, "%20")
            }
            //Percorre nossos objetos e gera o retorno
            for (var i in itens) {
                if (itens[i] != null) {
                    if (retorno != "") {
                        retorno += "&"
                    }
                    retorno += encode(i) + "=" + encode(itens[i])
                }
            }
            //Retornamos o valor
            return retorno
        }
    }
    //Adicionar requisição requisição
    this.add = function (metodo, url, valores, funcao_sucesso, funcao_erro) {
        //Adiciona os valores no array
        var i = requisicoes.length
        requisicoes[i] = []
        //Método da requisição
        requisicoes[i]["method"] = metodo.toUpperCase()
        //Url da requisição
        requisicoes[i]["url"] = url
        //Valores da requisição
        if (valores == null) {
            //Se era nulo, transformamos numa string vazia
            valores = ""
        } else if (valores.constructor == this.RequestValue) {
            /*Se o valor é da classe "RequestValue", obtemos
            transformamos numa string que será o novo valor*/
            valores = valores.getString()
        }
        requisicoes[i]["valor"] = valores
        //Funções (sucesso/erro)
        requisicoes[i]["funcao"] = funcao_sucesso
        requisicoes[i]["funcao_erro"] = funcao_erro
        //Processa as requisições (não necessariamente essa)
        Processa()
    }
    //Processa
    var Processa = function () {
        //Verifica se já está processando
        if (processando) {
            //Se já estamos processando, sai
            return
        }
        //Verifica se ainda há requisições
        if (!requisicoes[atual]) {
            //Se não há requisição, vamos sair
            return
        }
        //Indica que está processando
        processando = true
        //Função executada ao terminar a requisição
        var OnEnd = function (retorno) {
            //Executa as funções de erro/sucesso
            if (retorno == null) {
                //Verificamos se a função de erro é realmente uma função
                if (typeof (requisicoes[atual]["funcao_erro"]) == "function") {
                    //Se sim, a chamamos passando "null" como parâmetro
                    requisicoes[atual]["funcao_erro"](null);
                } else if (requisicoes[atual]["funcao_erro"] == true) {
                    /*Se o valor de "funcao_erro" for null, devemos chamar
                    a mesma função de sucesso com parâmetro "null"*/
                    requisicoes[atual]["funcao"](null);
                }
            } else {
                /*Se tivermos uma função de sucesso a executamos
                passando o valor de retorno como parâmetro*/
                if (typeof (requisicoes[atual]["funcao"]) == "function") {
                    requisicoes[atual]["funcao"](retorno)
                }
            }
            //Indica que não estamos mais processando
            processando = false
            //Processamos a próxima requisição
            atual++
            Processa()
        }
        //Processamento para método GET
        var requisicao_url = requisicoes[atual]["url"]
        if (
            requisicoes[atual]["method"] == "GET" &&
            requisicoes[atual]["valor"]
        ) {
            requisicao_url += "?" + requisicoes[atual]["valor"]
        }
        //Criamos a requisição
        xmlhttp.open(requisicoes[atual]["method"], requisicao_url, true)
        //Processamento para método POST
        if (requisicoes[atual]["method"] == "POST") {
            xmlhttp.setRequestHeader(
                "Content-type",
                "application/x-www-form-urlencoded; charset=UTF-8")
            xmlhttp.setRequestHeader('Content-length', requisicoes[atual]["valor"].length)
        }
        //Função executada na mudança de estado da requisição
        xmlhttp.onreadystatechange = function () {
            //Verificamos se o "readyState" é "4" (requisição finalizada)
            if (xmlhttp.readyState == 4) {
                //Verificamo o "status"
                if (xmlhttp.status == 200) {
                    //Se o status for 200, tudo OK !
                    OnEnd(xmlhttp.responseText) //Sucesso !
                } else {
                    //Se não for 200, problemas !
                    OnEnd(null) //Erro !
                }
            }
        }
        //Função executada quando ocorrerem erros
        try {
            //Nem sempre o "onerror" é suportado, por isso o try..catch
            xmlhttp.onerror = function () {
                OnEnd(null) //Erro !
            }
        } catch (erro) {
            //Vamos ter que "sobreviver" sem o onerror
        }
        //Parâmetro do método "send"
        var requisicao_sendvalue = null
        //Só é necessário se o método for POST
        if (requisicoes[atual]["method"] == "POST") {
            requisicao_sendvalue = requisicoes[atual]["valor"]
        }
        //Enviamos a requisição
        xmlhttp.send(requisicao_sendvalue)
        //Retorna true
        return true
    }
    //Retorna nossa classe
    return this
} ()
pagina.html
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title>Exemplo com AjaxClass</title>
    <meta name="author" content="Jonathan Coutinho Luz de Queiroz" />
    <script type="text/javascript" src="AjaxClass.js"></script>
    <script type="text/javascript">
        onload = function () {
            //Verificamos o suporte a AJAX
            if (AjaxClass) {
                //Valores que passaremos (modifique-os e veja o resultado da requisição)
                var valores = new AjaxClass.RequestValue()
                valores.setValue("Valor1", 50)
                valores.setValue("Outro_valor", "Olá !")
                valores.setValue("Pergunta", "Tudo bem com você ?")
                //Adiciona a requisição
                AjaxClass.add(
                        "GET", /*Método (recomendo que altere
                        para testar, o resultado será diferente)*/
                        "arquivo.php", //Url
                        valores, //Valores passados por GET
                        function (r) {
                            var txtResultadoRequisicao = document.createElement("textarea")
                            txtResultadoRequisicao.value = r
                            txtResultadoRequisicao.style.width = "100%"
                            txtResultadoRequisicao.style.height = "200px"
                            document.body.appendChild(txtResultadoRequisicao)
                        }, //Função executada quando houver sucesso
                        function () {
                            alert("Ocorreu um erro ao processar a requisição")
                        } //Função executada quando ocorrerem erros
                    )
            } else {
                alert("Desculpe, seu navegador não possui suporte a AJAX")
            }
        }
    </script>
</head>
<body>
    <h1>Exemplo de código utilizando AjaxClass</h1>
    Autor da classe: Jonathan Coutinho Luz de Queiroz
</body>
</html>
arquivo.asp
Se você está visualizando esse texto, parabéns !
O arquivo foi carregado corretamente por AJAX.
<%
'Esse código ASP foi criado para servir de exemplo para o AjaxClass
'Basicamente, esse script lista os valores vindos pelos métodos GET e POST
'Autor: Jonathan Coutinho Luz de Queiroz
'Contato: jonathan.jclq@gmail.com


'Função para listar valores de uma coleção
function Listar(a)
    for each i in a
        Response.Write("    " & i & " = """ & a(i) & """" & vbcrlf)
    next
end function
'Charset
Response.CharSet="UTF-8"
'Listamos os valores vindos por GET
Response.Write("Valores vindos por GET:" & vbcrlf)
Listar(Request.QueryString)
'Listamos os valores vindos por POST
Response.Write("Valores vindos por POST:" & vbcrlf)
Listar(Request.Form)
%>
arquivo.php
Se você está visualizando esse texto, parabéns !
O arquivo foi carregado corretamente por AJAX.
<?php
/*
Esse código PHP 5 foi criado para servir de exemplo para o AjaxClass
Basicamente, esse script lista os valores vindos pelos métodos GET e POST
Autor: Jonathan Coutinho Luz de Queiroz
Contato: jonathan.jclq@gmail.com
*/

//Função para listar valores
function Listar($a){
    foreach($a as $nome => $valor){
        echo '    ' . $nome . " = \"" . $valor . "\"\n";
    }
}
//Lista os valores passados por GET
echo "Valores vindos por GET:\n";
Listar($_GET);
//Lista os valores passados por POST
echo "Valores vindos por POST:\n";
Listar($_POST);
?>

Testem e postem o que acham, o que poderia ser melhorado, etc.

Scripts relacionados

  • Interface Ajax
    • Autor: Kakarotto
    • Descrição: Código pronto para executar ajax.
  • Ajax.Class
    • Autor: Kakarotto
    • Descrição: Outra classe simples para manipulação de ajax.
AnexosAnexos no fórum:

AjaxClass_example.rar

AjaxClass.js.rar

Link para o comentário
Compartilhar em outros sites

2 respostass a esta questão

Posts Recomendados

  • 0

Boa Jo,

Cara, as vezes eu acho que você lê minha mente...

Eu ia postar esses dias uma classe ajax =\ e ainda ia usar o mesmo título....agora vou ter que pensar em outro ¬¬

Boa man, vai ajudar bastante.

Link para o comentário
Compartilhar em outros sites

  • 0

Valeu, Eduardo. Depois vou ver se implemento a classe para suportar simultaneamente valores passados por GET e POST. Como foi criada inicialmente para atender às minhas necessidades específicas eu não implementei isso.

Quanto ao nome, a classe inicialmente chamava-se apenas "AJAX" (inclusive num dos sites que estou programando ainda está com esse nome rsrs). Mas pra postar aqui resolvi mudar, achei que somente "AJAX" não ficaria legal.

Depois vou pensar se permito a utilização do modo síncrono ao invés de somente assíncrono, mas acho que não. Até porque a classe não executa as requisições simultaneamente (o que pode sobrecarregar o navegador), ela cria uma "fila". No modo síncrono sequer seria necessário criar a fila.

Vou editar meu post para postar outras classes relacionadas e colocar um link para os arquivos compactados (como no seu post). Cheguei a ler o tópico de sua classe, mas ainda não testei (vou fazer agora).

Link para o comentário
Compartilhar em outros sites

Participe da discussão

Você pode postar agora e se registrar depois. Se você já tem uma conta, acesse agora para postar com sua conta.

Visitante
Responder esta pergunta...

×   Você colou conteúdo com formatação.   Remover formatação

  Apenas 75 emoticons são permitidos.

×   Seu link foi incorporado automaticamente.   Exibir como um link em vez disso

×   Seu conteúdo anterior foi restaurado.   Limpar Editor

×   Você não pode colar imagens diretamente. Carregar ou inserir imagens do URL.



  • Estatísticas dos Fóruns

    • Tópicos
      152,1k
    • Posts
      651,8k
×
×
  • Criar Novo...