Desenvolvimento - Javascript

Criando URLs únicas com Ajax

Veja neste artigo como criar uma URL única para exibir um conteúdo pelo Ajax e como executar scripts dessa página exibida.

por Gregory Monteiro



Nesse artigo irei abordar como criar URLs únicas e como retornar dados por JavaScript através de páginas que são chamadas pelo Ajax.

Alguns recursos usados nesse aqui foram descritos no artigo Segurança contra hacker no Ajax, então para melhor entendimento seria ideal lê-lo.

O conceito de URLs únicas são nomes fictícios criados dentro da mesma página para mostrar conteúdos diferentes.

Para fazer isso não existe maneira melhor do que criar um evento, através do JavaScript, que “leia” a URL e a interprete de acordo com a sua necessidade para exibição do conteúdo, que será visto mais a frente na listagem 3.

Nota: para criar URLs únicas os programadores usam de um artifício que o browser oferece escrever no final da URL um caractere “#” e após o identificador para o conteúdo que deverá ser exibido. Isso é feito porque o browser não interpreta mudanças feitas após esse caractere e por isso não acontece o refresh na página tornando o conteúdo estático.

Iniciando o exemplo

O exemplo que vamos criar é composto de quatro páginas sendo elas “index.html” (que fica na raiz do site) e as seguintes ficam dentro de uma pasta que denominei “include”. As páginas são “default.asp”, “ajax.asp” e “get.asp”.

Os links serão:

/index.html
/include/default.asp
/include/ajax.asp
/include/get.asp

No código da listagem 1 criei na linha 7 uma variável chamada “urlteste” que tem como valor inicial tudo que aparece escrito na URL da página após o caractere “#”.

Na linha 8 eu converti todo o conteúdo da variável criada para letras minúsculas.

Nas linhas 10 a 13 chamei o conteúdo da página “default.asp” e nas linhas 17 a 21 crei links para alterar a URL do nosso exemplo e tags onde serão retornados os dados do exemplo.

Listagem 1. Página inicial “index.html”

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
 <head>
 <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
 <title>DESMISTIFICANDO ALGUNS MISTÉRIOS DO AJAX</title>
 <script>
   var urlteste = window.location.hash.substring(window.location.hash.indexOf('#')+1,window.location.hash.length);
   urlteste = urlteste.toLowerCase();
  
   var novo = document.createElement('script');
   novo.setAttribute('type', 'text/javascript');
   novo.setAttribute('src', "include");
   document.getElementsByTagName('head')[0].appendChild(novo);
 </script>
 </head>
 <body>
   <a href=''>home</a><br>
   <a href='#exemplo1'>exemplo 1</a> |
   <a href='#exemplo2'>exemplo 2</a><br>
   <span id="resposta"></span><br>
   <span id="conteudo"></span>
 </body>
 </html>

Na listagem 2 criei duas variáveis xmlHttp, linha 26, para não gerar conflito quando o código executar, isso pode acontecer nas versões 6 e 7 do Internet Explorer.

A função “extraiScript” é a responsável por executar todo o elemento entre a tag “script”, como veremos a seguir, para tornar nossa vida de programador mais fácil quando quisermos retornar mensagens aos usuários com conteúdos presentes somente na página que é chamada pelo Ajax.

A função “show”, linhas 28 a 39, executa o código que de fato irá fazer o conteúdo da página índex.html mudar.

Listagem 2. Código da página “default.asp”

 <%
 VerificaReferencia = request.ServerVariables("HTTP_REFERER")
 if VerificaReferencia = "" then
   response.write "Você não tem permissão para visualizar esse conteúdo! :p"
   response.end
 end if
 response.expires=-1
 Response.Charset="ISO-8859-1"
 %>
 document.onkeydown = function(event){
   if(navigator.appName == 'Microsoft Internet Explorer'){
         if(window.event.keyCode == 123){
               return false;
         }
   }else{
         if(event.ctrlKey && event.shiftKey && event.keyCode == 74 || event.ctrlKey && event.keyCode == 85){
               return false;
         }
   }
 }

 document.oncontextmenu = function(){
   return false;
 }

 var xmlHttpINIT,xmlHttp;

 function show() {
   xmlHttpINIT = GetXmlHttpObject();
   if (xmlHttpINIT == null) {
         alert ("Seu browser não suporta AJAX!");
         return;
   }else{
         var url = "include/ajax.asp";
         xmlHttpINIT.onreadystatechange = stateChangedShow;
         xmlHttpINIT.open("GET",url,true);
         xmlHttpINIT.send(null);
   }
 }

 function stateChangedShow() {
   if (xmlHttpINIT.readyState==1 || xmlHttpINIT.readyState==2 || xmlHttpINIT.readyState==3) {
   }
   if (xmlHttpINIT.readyState==4) {
         extraiScript(xmlHttpINIT.responseText);
   }
 }

 function GetXmlHttpObject() {
   var xmlHttp = null;
   try {
         // Firefox, Opera 8.0+, Safari
         xmlHttp = new XMLHttpRequest();
   } catch (e) {
         // Internet Explorer
         try {
         xmlHttp = new ActiveXObject("Msxml2.XMLHTTP");
         } catch (e) {
         xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
         }
   }
   return xmlHttp;
 }

 function extraiScript(texto){
   var ini = 0;
   // loop enquanto achar um script
   while (ini!=-1){
         // procura uma tag de script
        ini = texto.indexOf('<script', ini);
         // se encontrar
         if (ini >=0){
               // define o inicio para depois do fechamento dessa tag
               ini = texto.indexOf('>', ini) + 1;
               // procura o final do script
               var fim = texto.indexOf('</script>', ini);
               // extrai apenas o script
               codigo = texto.substring(ini,fim);
               // executa o script
               novo = document.createElement("script")
               novo.text = codigo;
               document.body.appendChild(novo);
         }
   }
 }

 show();

Criando URLs únicas

Como falei anteriormente é necessário que algo fique executando no browser do cliente para poder interpretar que ouve alteração na URL, já que não irá acontecer o refresh da página.

Na listagem 3 o a função “redirURL”, linhas 11 a 22 é que interpreta a URL do browser e redireciona para o link certo. O método é muito simples é passada a ultima string registrada na variável “urlteste” para essa função e comparado com a nova string capturada por essa mesma variável, se os valores forem diferentes então é executada uma a função “showResultado” passando o valor desejado para ela.

Lembrando que o valor da variável “urlteste” foi definido que seria tudo que estaria escrito depois do caractere “#” na URL.

A função “redirURL” possui também um timeout que executa ela mesma em períodos de 200 milissegundos, linha 21.

Nota: para que essa função funcione corretamente é necessário que o timeout dela esteja entre 200 a 300 milissegundos, pois abaixo desse valor pode não executar corretamente o código no Internet Explorer e acima já demora muito para uma resposta.

Observe também que o valor esta entre 200 a 300 milissegundos, pois pode ocorrer em certas situações que 200 milissegundos também gerar erros de execução do script pelo Internet Explorer.

A função “showResultado”, linhas 24 a 38, é a encarregada de executar a página “get.asp” passando uma variável que nomeei “tipo”, através do método POST.

Observe que na linha 46 a função “extraiScript” é chamada e é passado o conteúdo retornado pela página “get.asp”

Listagem 3. Código da página “ajax.asp”

 <%
 VerificaReferencia = request.ServerVariables("HTTP_REFERER")
if VerificaReferencia = "" then
   response.write "Você não tem permissão para visualizar esse conteúdo! :p"
  response.end
 end if
 response.expires=-1
 Response.Charset="ISO-8859-1"
%>
 <script>
 function redirURL(url_teste){
   urlteste = window.location.hash.substring(window.location.hash.indexOf('#')+1,window.location.hash.length);
 
   if(url_teste != urlteste){
         if(urlteste == "exemplo1"){
               showResultado(1);
        }else if(urlteste == "exemplo2"){
               showResultado(2);
         }
   }
   setTimeout("redirURL(urlteste);",200);
 }

 function showResultado(tipo) {
   xmlHttp = GetXmlHttpObject();
   if (xmlHttp == null) {
         alert ("Seu browser não suporta AJAX!");
         return;
   }else{
         var url = "include/get.asp";
         var varStr;
         varStr = "tipo="+tipo;
         xmlHttp.onreadystatechange = stateChanged2;
         xmlHttp.open("POST",url,true);
         xmlHttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
         xmlHttp.send(varStr);
   }
 }

 function stateChanged2() {
   if (xmlHttp.readyState == 1 || xmlHttp.readyState == 2 || xmlHttp.readyState == 3) {
         document.getElementById("conteudo").innerHTML = "carregando...";
   }
   if (xmlHttp.readyState == 4) {
         document.getElementById("conteudo").innerHTML = xmlHttp.responseText;
         extraiScript(xmlHttp.responseText);
   }
 }

 function loadPag(urlteste){
   if(urlteste != "" && isNaN(urlteste)){
         if(urlteste == "exemplo1"){
               showResultado(1);
         }else if(urlteste == "exemplo2"){
               showResultado(2);
         }
   }
 }

 document.onload = loadPag(urlteste);
 setTimeout("redirURL(urlteste);",200);
 </script>

Ate então o código executa perfeitamente porem o que acontece quando o usuário der refresh na página ou acessar ela pela primeira vez com uma URL que tenha já alguma string após o caractere “#”, como na figura 1?

Página index.html sem a execução da função loadPag no evento onload

Figura 1. Página “index.html” sem a execução da função “loadPag” no evento onload

Certamente não irá acontecer nada, pois sem um evento que especifique o que fazer no load da página não será apresentado nenhum conteúdo. Por isso criamos na página “ajax.asp” (Listagem 3) a função “loadPag”, linhas 50 a 58 que interpreta o valor da variável “urlteste” e executa o conteúdo desejado. Lembrando que o valor inicial da variável “urlteste” foi setado na página “índex.html” (Listagem 1) nas linhas 7 e 8.

Na listagem 4 a linha 10 retorna uma string com o valor do campo “tipo” passado pelo método POST através da função “showResultado”. A linha 13 retorna também uma string porem pelo JavaScript.

Listagem 4. Código da página “get.asp”

<%
 VerificaReferencia = request.ServerVariables("HTTP_REFERER")
 if VerificaReferencia = "" then
   response.write "Você não tem permissão para visualizar esse conteúdo! :p"
   response.end
 end if
 response.expires=-1
 Response.Charset="ISO-8859-1"
 %>

 <h3>teste exemplo <%=request.form("tipo")%> concluído</h3>

 <script>
 document.getElementById("resposta").innerHTML = "teste de exemplo <%=request.form("tipo")%> de retorno JavaScript concluído";
 </script>

Note que se você retirar a linha 46 da página “ajax.asp” o código em JavaScript não será executado retornado algo semelhante a figura 2.

Página index.html sem a execução da função extraiScript

Figura 2. Página “index.html” sem a execução da função “extraiScript”

As figuras 3, 4 e 5 mostram as execuções da nossa página com os links que criamos.

Após navegar pelo nosso exemplo use também as opções de voltar e avançar do browser que o resultado também será o mesmo!

 Página index.html no modo inicial

Figura 3. Página “index.html” no modo inicial

Página index.html ao clicar ou acessar diretamente a URL

Figura 4. Página “index.html” ao clicar ou acessar diretamente a URL “http://localhost:83/#exemplo1”

Página index.html ao clicar ou acessar diretamente a URL

Figuras 5. Página “index.html” ao clicar ou acessar diretamente a URL “http://localhost:83/#exemplo2”

Conclusão

Nesse artigo foi criado um exemplo prático de como implementar URLs únicas no seu site e como passar informações de páginas requisitadas pelo Ajax pelo JavaScript.

Referência

Função “extraiScript”

http://forum.imasters.com.br/index.php?showtopic=165277
Gregory Monteiro

Gregory Monteiro - Programador/administrador dos sites da DevMedia. Formado em sistemas de informação. Certificados SEO pela mestreseo e ietv. Certificado CMMI pela FIOCRUZ. Curso de web developer pela microcamp. Administrador de redes. Conhecimentos em C#, VB.NET, ASP, PHP, JSP, HTML, XHTML, HTML5, Ajax, CSS3, jQuery, JavaScript, SQL Server, MySQL, Firebird, IIS 6/7, NGINX, Linux, WPF