Introdução

 

Na parte anterior, vimos como podemos utilizar o evento onunload do javascript para detectar quando o usuário acessa um outro site ou quando ele fecha o browser. Entretanto, o evento onunload possui uma limitação, já que ele não faz distinção entre páginas da mesma aplicação ou páginas de outros sites. Esse evento sempre é chamado em resposta à saída da página atual. Como uma aplicação web normalmente é composta de várias páginas, temos que fazer com que o evento onunload somente seja chamado quando o usuário sair da aplicação, e não de uma página dela. É sobre isso que este artigo tratará.

 

 

O problema

 

Inicialmente, vamos reproduzir o problema. Com o Web Site Saida aberto no Visual Studio 2005, vá ao Solution Explorer e clique com o botão direito sobre o projeto. Escolha a opção Add New Item. Selecione o template Web Form e nomeie-o Pagina2.aspx, conforme a imagem abaixo:

 

 

 


Vá para o modo de Design e, a partir da Toolbox, arraste um controle HyperLink para a página. Na janela de propriedades do controle, vá a propriedade NavigateUrl e clique no botão . Na janela Select URL, selecione a página Pagina1.aspx.

 

 

 

 

Altere também a propriedade Text para “Link para a página 1. Acabamos de criar um link para a Pagina1.aspx. Agora, na Pagina1.aspx, vamos criar um link para a Pagina2.aspx. Abra a Pagina1.aspx em modo Design e arraste um controle HyperLink para ela. Configure as seguintes propriedades:

 

Controle

NavigateUrl

Text

HyperLink

~/Pagina2.aspx

Link para a página 2

 

 

No Solution Explorer, clique com o botão direito do mouse sobre Pagina1.aspx e escolha a opção View in Browser. Você verá uma tela parecida com a seguinte:

 

 

 

 

Clique no link que nos leva à Pagina2.aspx. Ao fazermos isso, o evento onunload é disparado, fazendo que a função javascript finaliza(), criada na segunda parte do artigo, seja chamada, expirando a sessão. Para comprovarmos que isso aconteceu, vá ao Control Panel do Windows ® Administrative Tools ® Event Viewer. Selecione o log Application e veja o log que foi gerado por nossa aplicação.

 

 

A solução

 

Para resolver o problema exposto anteriormente, iremos utilizar frames. Os frames do HTML dividem uma página web em partes independentes. Assim, podemos ter uma página composta por N outras páginas. Em nosso exemplo, só utilizaremos um único frame e a navegação entre as páginas ocorrerá dentro dele. O tratamento do evento onunload ficará na página que contém o frame. Assim, a troca de páginas de nossa aplicação, que ocorrerá dentro do frame, não provocará a chamada do evento onunload, que só será disparado quando acessarmos um outro site ou fecharmos o browser.

 

No Solution Explorer, clique com o botão direito do mouse sobre o Web Site Saida e escolha a opção Add New Item. Escolha o template HTML Page e no campo Name, escreva index.htm. Vá para o modo Source da página, para termos acesso ao código HTML. Substitua o conteúdo pelo código abaixo:

 

 

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" >

<head>

    <title>Untitled Page</title>

    <script language="javascript" type="text/javascript">

    function finaliza()

    {

        var xmlHttp=false;

 

        try {

          xmlHttp = new XMLHttpRequest();

        } catch (e1) {

          try {

            xmlHttp = new ActiveXObject("Msxml2.XMLHTTP");

          } catch (e2) {

              xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");

          }

        }

       

        xmlHttp.open("GET", "Finaliza.aspx", true);

        xmlHttp.send(null);

    }   

    </script>   

</head>

    <frameset rows="100%" cols="100%" onunload="finaliza();">

        <frame src="Pagina1.aspx" frameborder="0" />

    </frameset>

</html>

 

 

Perceba que, além de definirmos um frame que ocupará a janela inteira do browser, também foi colocado o código da função javascript finaliza() bem como sua chamada no evento onunload da tag <frameset>. Assim precisamos ir à Pagina1.aspx e retirar a declaração da função javascript finaliza() e a chamada do evento onunload.

 

No Solution Explorer, clique com o botão direito do mouse sobre a página index.htm e escolha a opção View in Browser. Você verá a página carregada, com o conteúdo da Pagina1.aspx dentro do frame. Clique no link para ir à Pagina2.aspx e verifique no Event Viewer do Windows que o log de sessão expirada não foi gerado. Clique no link para voltar à Pagina1.aspx e confirme novamente que o log não foi gerado. Perceba também que enquanto navegamos entre as páginas, a URL na barra de endereços do browser não se altera. Isso acontece porque a navegação ocorre dentro do frame, enquanto que a URL aponta para a página que contém o frame. Agora, experimente acessar outro site ou fechar o browser. Volte ao Event Viewer e confirme que o log foi gerado, comprovando que o evento onunload foi disparado.

 

 

Conclusão

 

Com esta alteração, a aplicação web agora é capaz de gerar notificações de saída do usuário no momento certo, já que agora o evento onunload não é disparado a cada mudança de página. Nesta série de artigos, vimos como utilizar recursos do lado servidor e do lado cliente para detectar quando o usuário deixa uma aplicação ASP.NET. Combinando os dois, estudamos as limitações e as soluções para contornar as mesmas, permitindo que algum processamento seja feito neste momento.

 

 

Referências

 

Código fonte do exemplo deste artigo

http://www.aspneti.com/artigos/ExemploDetectarSaida.zip

 

Gerenciamento de Estado no Servidor – Parte 1 http://www.msdnbrasil.com.br/sharepedia/visualizarartigo.aspx?id=57763

 

Gerenciamento de Estado no Servidor – Parte 2

http://www.msdnbrasil.com.br/sharepedia/visualizarartigo.aspx?id=57906

 

Dynamic HTML and XML: The XMLHttpRequest Object

http://developer.apple.com/internet/webcontent/xmlhttpreq.html

 

Frames in HTML documents

http://www.w3.org/TR/html401/present/frames.html

 

 

Sobre o Autor

 


Ricardo Oneda Pereira de Toledo é formado em Processamento de Dados pela Faculdade de Tecnologia de São Paulo, é MCADMicrosoft Certified Application Developer, com ênfase em aplicações Web com C# e Banco de Dados SQL Server 2000 e é MVP – Most Valuable Professional em ASP/ASP.NET. Atualmente trabalha como Analista de Sistemas no desenvolvimento de aplicações Web. Visite o blog em http://oneda.mvps.org/blog