Back-End

10 jan, 2007

Notícias atualizadas com Feed e Ajax

Publicidade

Olá amigos que acompanham a seção ASP.
Neste artigo será desenvolvido um pequeno
sistema de notícias
atualizadas automaticamente baseando-se no sistema de RSS Feed
da Folha de São Paulo e utilizando a tecnologia Ajax na
leitura das notícias.

Informo aos amigos desenvolvedores que este é um exemplo
concatenado especificadamente com os feeds da Folha. Se algum
desenvolvedor por ventura adicionar outros canais, terão
que realizar alterações no script.

Então mãos a obra. Abaixo segue o código
comentado linha a linha para fácil entendimento de como
o script foi concatenado.

Crie um arquivo chamado “lendo.asp” e cole o código
no arquivo criado.

<%
‘Declaramos todas as variáveis
que iremos utilizar em nosso script.
Dim arrCanaisFolha(19), i, QueryString_UrlFeed, feed_selected,
codFeed, endFeed, ArrUrl, creditos

‘Variável que será alimentada pelo código
do canal do feed
QueryString_UrlFeed = Request.QueryString("UrlFeed")
‘Declaramos uma constante indicando que
as notícias do
feed começam do 8º nó do xml.

Const Nodo_Inicial = 8

‘Gravamos em um array todos os canais de rss da folha.
‘Observe que depois das descrições, temos o caracter
_ (underline), o caracter separa a descrição do
endereço do feed, abaixo utilizarei a função
Split para separar os dados

arrCanaisFolha(0) = "Brasil_brasil"
arrCanaisFolha(1) = "Ci&ecirc;ncia_ciencia"
arrCanaisFolha(2) = "Colunas – Bras&iacute;lia Online_colunas/brasiliaonline"
arrCanaisFolha(3) = "Colunas – Di&aacute;rio, Depress&atilde;o
e Fama_colunas/diariodepressaoefama"
arrCanaisFolha(4) = "Colunas – Futebol na Rede_colunas/futebolnarede"
arrCanaisFolha(5) = "Colunas – Ooops!_colunas/ooops"
arrCanaisFolha(6) = "Colunas – Regra 10_colunas/regra10"
arrCanaisFolha(7) = "Cotidiano_cotidiano"
arrCanaisFolha(8) = "Dinheiro_dinheiro"
arrCanaisFolha(9) = "Educa&ccedil;&atilde;o_educacao"
arrCanaisFolha(10) = "Em cima da hora_emcimadahora"
arrCanaisFolha(11) = "Equil&iacute;brio_equilibrio"
arrCanaisFolha(12) = "Especial – 2006 – Copa_especial/2006/copa"
arrCanaisFolha(13) = "Esporte_esporte"
arrCanaisFolha(14) = "Ilustrada_ilustrada"
arrCanaisFolha(15) = "Inform&aacute;tica_informatica"
arrCanaisFolha(16) = "Mundo_mundo"
arrCanaisFolha(17) = "Painel do Leitor_paineldoleitor"
arrCanaisFolha(18) = "Pensata_pensata"
arrCanaisFolha(19) = "Turismo_turismo"

%>
<html>
<head>
<style type="text/css">
.link{font-family:arial; font-size:14px; color:black; text-decoration:none;}
.link:hover{color:blue; text-decoration:underline;}
</style>
</head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<title>Leitor de RSS</title>
<body leftmargin="0" topmargin="0" marginwidth="0" marginheight="0" onLoad="Ajax(‘conteudo_noticia’,’Ler_Noticia.asp?Nodo=<%=Nodo_Inicial%>’);">
<script language="JavaScript" type="text/javascript" src="funcoes_ajax.js"></script>
<script type="text/javascript" language="JavaScript">
// Scripts do AJAX //
var enableCache = false;
var jsCache = new Array();
var AjaxObjects = new Array();
                       
function ShowContent(divId,ajaxIndex,url){
            document.getElementById(divId).innerHTML
= AjaxObjects[ajaxIndex].response;
             
             if(enableCache){
                        jsCache[url]
= AjaxObjects[ajaxIndex].response;
             }         AjaxObjects[ajaxIndex]
= false;
}
                       
function Ajax(divId,url){
            document.getElementById(divId).innerHTML
= ‘<br><div align="center"><img src="aguarde.gif" width="16" height="16" vspace="2" /><font
face="tahoma" size="2">&nbsp;&nbsp;Aguarde
Carregando…</font></div><br><br>’;

            if(enableCache && jsCache[url]){
                        document.getElementById(divId).innerHTML
= jsCache[url];
                        return;
            }         
           
            var ajaxIndex
= AjaxObjects.length;
    AjaxObjects[ajaxIndex] = new sack();
    AjaxObjects[ajaxIndex].requestFile = url;
    AjaxObjects[ajaxIndex].onCompletion = function(){ ShowContent(divId,ajaxIndex,url);
};
    AjaxObjects[ajaxIndex].runAJAX();
}

function carrega_feed(){
            document.location.href=’Lendo.asp?UrlFeed=’
+ document.frm_feed.endereco_feed.value;
}
</script>
<strong><font size="4" face="arial">LEITOR
DE RSS FOLHA- AJAX</font></strong><br>
<br>
<table width="577" border="0" cellspacing="0" cellpadding="0">
  <form name="frm_feed" method="post" action="Lendo.asp">
    <tr>
      <td width="188"><font size="2" face="arial"><strong>Selecione
o Canal Desejado:</strong></font></td>
      <td width="389"> <div align="left">
          <select name="endereco_feed" onChange="carrega_feed();">
                          <option>—
Selecione —</option>
                          <%
                          ‘Abaixo
montaremos um looping com a array de canais que gravamos acima.
                          ‘Utilizaremos
LBound para pegar a menor dimensão do Array e
UBound para pegar a maior
dimensão do Array
                          For
i = LBound(arrCanaisFolha) To UBound(arrCanaisFolha)
                                    ‘Geramos
um array baseando-se na função Split, como citado acima separaremos
a descrição do endereço do feed.

                                    ArrCombo
= Split(arrCanaisFolha(i),"_")

                                    ‘Verificamos
se o código do canal atual é o mesmo do looping,
quando a condição for verdadeira selecionaremos
o canal com a variável feed_selected

                                    If
CStr(QueryString_UrlFeed) = CStr(i) Then
                                                feed_selected
= "selected"
                                    Else
                                                feed_selected
= Null
                                    End
If
                                    ‘Exibimos
as opções do listbox no browser, a variável i representa
a contagem do looping, o ArrCombo(0), indica ao sistema para pegar a descrição
do array.

                                    ‘Acima
separamos com a função Split, exemplo quando ArrCombo(0) for
de dimensão 0 a descrição é exibida, quando ArrCombo(1)
for de dimensão 1 o endereço do feed é exibido.

                                    Response.Write "<option
value=""" & i & """ " & feed_selected & ">" & ArrCombo(0) & "</option>"
                          ‘Terminamos
o looping com o comando Next

                          Next
                          %>
          </select>
        </div></td>
    </tr>
  </form>
</table>
<br>
<%
‘Verificamos nesta condição se a variável
QueryString_UrlFeed, contem um valor numérico caso a mesma
não contenha, pegamos o primeiro canal do feed.

If Not IsNumeric(QueryString_UrlFeed) = True Then
           
Nesta condição a variável codFeed, com valor 0 seleciona
o primeiro canal do feed.

            codFeed
= 0
Else
           
Nesta condição a variável codFeed, pega o valor numérico
da variável QueryString_UrlFeed

            codFeed
= QueryString_UrlFeed
End If

‘Geramos um array com a função Split, para pegarmos
o endereço do feed.

ArrUrl = Split(arrCanaisFolha(codFeed),"_")

‘Instanciamos o componente XMLHTTP, para realizarmos a consulta
no site da folha
Set objXMLHttp = Server.CreateObject("Microsoft.XMLHTTP")
‘Observe que o array ArrUrl(1) está com dimensão
1, o que significa que iremos trazer o endereço do feed.
‘Abriremos a solicitação do XMLHTTP.

objXMLHttp.Open "GET", "http://feeds.folha.uol.com.br/folha/" & ArrUrl(1) & "/rss091.xml",
False
‘Informaremos no cabeçalho de nossa solicitação
que o conteúdo do arquivo é XML

objXMLHttp.setRequestHeader "Content-Type","text/xml"
‘Enviamos a solicitação
objXMLHttp.Send()

‘Verificamos se a solicitação retornou o status
200, processado com êxito.

If objXMLHttp.Status = 200 Then
            ‘Instanciamos
o componente XMLDOM para iniciarmos a leitura dos dados.

            Set objXML
= Server.CreateObject("Microsoft.XMLDOM")
            ‘
            objXML.async
= False
            ‘Carregamos
o conteúdo retornado pelo componente XMLHTTP.

            objXML.loadXML(objXMLHttp.responsexml.xml)
           
            ‘Verificamos
se o arquivo XML não possue erros.

            If objXML.parseError.errorCode <> 0
Then
                        ‘Caso
possua algum erro, exibimos o erro no browser

                        Response.Write
objXML.parseError.reason
            Else
                        ‘Criamos
um objeto chamado raiz para exibirmos os dados

                        Set
raiz = objXML.documentElement
                       
                        ‘Iniciaremos
um looping para exibir as notícias retornadas pelo xml, pegaremos o
valor do Nodo_inicial e contaremos todos os Nodos subtraindo pelo Nodo_Inicial.
                        ‘Com
isso iremos obter o valor do primeiro nó que contém a notícia
até o ultimo nó de notícias.

                        For
i = Nodo_Inicial To raiz.childNodes.Item(0).childNodes.length – Nodo_Inicial
                                    ‘Exibimos
os titulos da notícia para o browser.

                                    Response.Write "<a
class=""link"" href=""javascript:Ajax(‘conteudo_noticia’,’Ler_Noticia.asp?Nodo=" & i & "’);"">&raquo;&raquo; " & raiz.childNodes.Item(0).childNodes.Item(i).childNodes.Item(0).Text & "</a><br>"
                                    ‘Gravamos
em um session o título da noticia para exibirmos no arquivo de visualização
da notícia

                                    Session("titulo_" & i)
= raiz.childNodes.Item(0).childNodes.Item(i).childNodes.Item(0).Text
                                    ‘Gravamos
em um session o conteúdo da noticia para exibirmos no arquivo de visualização
da notícia

                                    Session("noticia_" & i)
= raiz.childNodes.Item(0).childNodes.Item(i).childNodes.Item(2).Text
                        Next
                                    ‘Variável
que contém os creditos existentes no Feed da Folha

                                    creditos
= "<font face=""tahoma"" size=""1"">" & raiz.childNodes.Item(0).childNodes.Item(0).childNodes.Item(0).Text & " – "  & raiz.childNodes.Item(0).childNodes.Item(4).childNodes.Item(0).Text & "</font>"
                       
                        ‘Destruimos
o objeto raiz

                        Set
raiz = Nothing      
                        ‘Destruimos  instância
ao componente XMLDOM

                        Set
objXML = Nothing
            End If
Else
            ‘Informamos
no browser que ocorreu um erro durante o processo.

            Response.Write "Erro
ao processar solicitação…"
            ‘Paramos
o programa

            Response.End
End If

‘Destruimos a instância ao componente
XMLHTTP

Set objXMLHttp = Nothing
%>
<br>
<table width="577" height="223" border="0" cellpadding="0" cellspacing="0" style="border:1px
solid black;">
  <tr>
    <td width="577" height="221" valign="top"><div
id="conteudo_noticia"></div></td>
  </tr>
</table>
<%
‘Exibimos os créditos existentes no RSS da Folha.
Response.Write creditos
%>
</body>
</html>

Observe que, nas primeiras tags HTML, o script realiza a chamada
em um arquivo chamado “funções_ajax.js”.
Utilizo este bloco de funções pois, além
de facilitar a ligação com AJAX, também
o instânciamento do XMLHTTP torna-se compatível
com todos browsers. Esse arquivo de funções é muito útil para
trabalharmos com AJAX.

Próximo passo: crie um arquivo chamado “lendo_noticia.asp” e
cole o código abaixo.

<%
‘Variável responsável pelo código da notícia
QueryString_Nodo = Request.QueryString("Nodo")

‘Verificamos se o código da notícia possue valor
numérico.

If Not IsNumeric(QueryString_Nodo) = True Then
            ‘Caso
a variável não possua valor numérico, exibimos o erro no
browser.

            Response.Write "Erro
ao carregar notícia!!!"
            ‘Paramos
o programa

            Response.End
End If

‘Função responsável por transformar códigos
em HTML

Function TransformaHTML(strHTML)
            strHTML
= Replace(strHTML, "&lt;","<")
            strHTML
= Replace(strHTML, "&gt;",">")
            strHTML
= Replace(strHTML, "&quot;","""")
            strHTML
= Replace(strHTML, "<a ","<a target=""_blank"""" ")
            TransformaHTML
= strHTML
End Function

‘Exibimos a notícia no browser, note que utilizei a opção
Server.HTMLEncode, para codificar a solicitação
em HTML, pois quando não estava utilizando estive com
problemas de acentuação na solicitação
em AJAX, neste caso os acentos são transformados em código
no HTML, e a função TransformaHTML(), é reponsável
de separar o texto de tags html.

Response.Write "<font face=""arial"" size=""2""><div
align=""center""><strong>" & TransformaHTML(Server.HTMLEncode(Session("titulo_" & QueryString_Nodo))) & "</strong></div><br>" & TransformaHTML(Server.HTMLEncode(Session("noticia_" & QueryString_Nodo))) & "</font>"
%>

Próximo passo: crie um arquivo chamado “funcoes_ajax.js”,
cole o código no arquivo criado.

/* Simple AJAX Code-Kit (SACK) v1.6.1 */
/* ©2005 Gregory Wild-Smith */
/* www.twilightuniverse.com */
/* Software licenced under a modified X11 licence,
   see documentation or authors website for more details */

function sack(file) {
this.xmlhttp = null;

this.resetData = function() {
this.method = "POST";
  this.queryStringSeparator = "?";
this.argumentSeparator = "&";
this.URLString = "";
this.encodeURIString = true;
  this.execute = false;
  this.element = null;
this.elementObj = null;
this.requestFile = file;
this.vars = new Object();
this.responseStatus = new Array(2);
  };

this.resetFunctions = function() {
  this.onLoading = function() { };
  this.onLoaded = function() { };
  this.onInteractive = function() { };
  this.onCompletion = function() { };
  this.onError = function() { };
this.onFail = function() { };
};

this.reset = function() {
this.resetFunctions();
this.resetData();
};

this.createAJAX = function() {
try {
this.xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
} catch (e1) {
try {
this.xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
} catch (e2) {
this.xmlhttp = null;
}
}

if (! this.xmlhttp) {
if (typeof XMLHttpRequest != "undefined") {
this.xmlhttp = new XMLHttpRequest();
} else {
this.failed = true;
}
}
};

this.setVar = function(name, value){
this.vars[name] = Array(value, false);
};

this.encVar = function(name, value, returnvars) {
if (true == returnvars) {
return Array(encodeURIComponent(name), encodeURIComponent(value));
} else {
this.vars[encodeURIComponent(name)] = Array(encodeURIComponent(value),
true);
}
}

this.processURLString = function(string, encode) {
encoded = encodeURIComponent(this.argumentSeparator);
regexp = new RegExp(this.argumentSeparator + "|" +
encoded);
varArray = string.split(regexp);
for (i = 0; i < varArray.length; i++){
urlVars = varArray[i].split("=");
if (true == encode){
this.encVar(urlVars[0], urlVars[1]);
} else {
this.setVar(urlVars[0], urlVars[1]);
}
}
}

this.createURLString = function(urlstring) {
if (this.encodeURIString && this.URLString.length) {
this.processURLString(this.URLString, true);
}

if (urlstring) {
if (this.URLString.length) {
this.URLString += this.argumentSeparator + urlstring;
} else {
this.URLString = urlstring;
}
}

// prevents caching of URLString
this.setVar("rndval", new Date().getTime());

urlstringtemp = new Array();
for (key in this.vars) {
if (false == this.vars[key][1] && true == this.encodeURIString)
{
encoded = this.encVar(key, this.vars[key][0], true);
delete this.vars[key];
this.vars[encoded[0]] = Array(encoded[1], true);
key = encoded[0];
}

urlstringtemp[urlstringtemp.length] =
key + "=" +
this.vars[key][0];
}
if (urlstring){
this.URLString += this.argumentSeparator + urlstringtemp.join(this.argumentSeparator);
} else {
this.URLString += urlstringtemp.join(this.argumentSeparator);
}
}

this.runResponse = function() {
eval(this.response);
}

this.runAJAX = function(urlstring) {
if (this.failed) {
this.onFail();
} else {
this.createURLString(urlstring);
if (this.element) {
this.elementObj = document.getElementById(this.element);
}
if (this.xmlhttp) {
var self = this;
if (this.method == "GET") {
totalurlstring = this.requestFile + this.queryStringSeparator
+ this.URLString;
this.xmlhttp.open(this.method, totalurlstring, true);
} else {
this.xmlhttp.open(this.method, this.requestFile, true);
try {
this.xmlhttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded")
} catch (e) { }
}

this.xmlhttp.onreadystatechange = function() {
switch (self.xmlhttp.readyState) {
case 1:
self.onLoading();
break;
case 2:
self.onLoaded();
break;
case 3:
self.onInteractive();
break;
case 4:
self.response = self.xmlhttp.responseText;
self.responseXML = self.xmlhttp.responseXML;
self.responseStatus[0] = self.xmlhttp.status;
self.responseStatus[1] = self.xmlhttp.statusText;

if (self.execute) {
self.runResponse();
}

if (self.elementObj) {
elemNodeName = self.elementObj.nodeName;
elemNodeName.toLowerCase();
if (elemNodeName == "input"
|| elemNodeName == "select"
|| elemNodeName == "option"
|| elemNodeName == "textarea") {
self.elementObj.value = self.response;
} else {
self.elementObj.innerHTML = self.response;
}
}
if (self.responseStatus[0] == "200") {
self.onCompletion();
} else {
self.onError();
}

self.URLString = "";
break;
}
};

this.xmlhttp.send(this.URLString);
}
}
};

this.reset();
this.createAJAX();
}

Pronto! Salve os arquivos e execute o projeto!