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

XMLHttpRequest e document.write


johnwww

Pergunta

Olá a todos, tenho um webserver microcontorlado, que quando digito a seguinte url no browser : http://10.0.5.48/get_data?type=temperature , ele retorna a temperatura local. Gostaria de gerar essas temperaturas em fila, na tela do browser, mas quando faço a segunda requisição da temperatura, ela apaga a primeira, pois atualiza a página. Estou usando o objeto XMLHttpRequest, para pegar esses dados, sem carregar a página. O problema é que o script que está descrito abaixo, só mostra o valor uma vez e trava no firefox, e no IE7, só mostra todos os valores de uma vez, ficando o browser um grande tempo congelado. Utilizei para teste, um array para armazenar as temperaturas e, após esse array completo, mostrar na tela com o document.write, via loop. Funcionou, mas eu tenho que ir mostrando os valores logo quando disponíveis. Com certeza, o problema desse script é a implementação do document.write, mas não estou conseguindo descobrir o que está errado, pois estou iniciando os estudos em javascript.

Desde já, agrqdeço a colaboração.



<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>DHTML - JavaScript - XMLHttpRequest test 2</title><meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<meta http-equiv="Content-Style-Type" content="text/css" />
<meta http-equiv="Content-Script-Type" content="text/javascript" /><script type="text/javascript">
<!--

// Global constant (const doesn't work on IE 6, then var is applied instead)var CGI_funcName = "http:./get_data?type=temperature";var i=0;

// issue request to server
function sendXMLHttpReq( method, url, async, callback, txt ) {
var req = false;
// branch for IE/Windows ActiveX version
if(window.ActiveXObject) {
try {
req = new ActiveXObject("Msxml2.XMLHTTP");
} catch(e) {
try {
req = new ActiveXObject("Microsoft.XMLHTTP");
} catch(e) {
req = false;
}
}
// branch for native XMLHttpRequest object
} else if( window.XMLHttpRequest ) {
try {
req = new XMLHttpRequest();
} catch(e) {
req = false;
}
}
if( req ) {
req.open( method, url, async );
// cancel cache on IE
req.setRequestHeader("If-Modified-Since","Thu, 01 Jun 1970 00:00:00 GMT");
if ( callback ) {
req.onreadystatechange =
function() { // when successfully completed
if ( (req.readyState == 4) && (req.status == 200) ) {
// hand the data to callback
callback( req.responseText );
}
}
}
req.send( txt );
}
}

function show_in_browser(temp) {
document.write(temp + "<br>");
}

function read_temperature() {
for(i=0; i<10; i++){
sendXMLHttpReq( "GET", CGI_funcName, false, show_in_browser, " " );
}
}

// -->
</script>
</head><body>
<!-- Form 1 -->
<h2>Form 1</h2><form id="FM1" action=""> <input type="button" value="set" onclick="read_temperature()" style="width: 64px"/></td>

</form>
</body>
</html>

[/codebox]

Link para o comentário
Compartilhar em outros sites

9 respostass a esta questão

Posts Recomendados

  • 0

Bom, já que está certo de que o problema está na implementação do document.write, então nem vou dar uma olhada no código, admito que to com uma pequena preguiça rsrsrs. Não use o document.write, senão ele vai apagar o documento todo, e ae perde o sentido do ajax. Coloque tudo numa div:

function show_in_browser(temp) {
document.getElementById('div1').innerHTML+=temp
}

Coloca uma div no seu documento com qualquer id, pode colocar igual ao do código que passei (div1) pra te ajudar em primeiro instante.

Kelabrassssssss

Link para o comentário
Compartilhar em outros sites

  • 0

Fala KaKarotto tudo bem, muito obrigado pela atenção. Fiz a alteração no código, passou a funcionar no firefox, mas com aquele problema de só aparecerem todas as temperaturas de uma vez, ficando o browser muito tempo parado esperando. Se as temperaturas fossem mostradas logo após aquisitadas, reduziria esse incômodo da espera.

Agora funcionando no firefox e conseguindo debugar, percebi que, rodando o script passo a passo, aparecem as temperaturas logo após aquistadas, e não entendi porque.

Vou continuar testando, e se eu conseguir algum progresso te escrevo.

Obrigado

Link para o comentário
Compartilhar em outros sites

  • 0

Consegui exibir as temperaturas logo após aquisitadas. O erro era que eu estava usando o XMLHttpRequest, de maneira síncrona, mandando um "false" para a função sendXMLHttpReq. Não entendi direito porque passou a funcionar, mas tudo bem.

Apareceu outro problema. Aumentei o loop da função read_temperature para 1000, e voltou aquele problema de as temperaturas só aparecerem todas de uma vez, e quando aumentei o loop para 10 000, o browser travou.

Como esse loop terá umas 30 000 voltas, terei de resolver mais esse caso.

Se você tiver mais uma idéia para me ajudar, ficarei mutio grato. Estou postando o código novamente, já com as alterações.

Muito obrigado pela ajuda.

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>DHTML - JavaScript - XMLHttpRequest test 2</title>

<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<meta http-equiv="Content-Style-Type" content="text/css" />
<meta http-equiv="Content-Script-Type" content="text/javascript" />

<script type="text/javascript">
<!--
// Global constant (const doesn't work on IE 6, then var is applied instead)

var CGI_funcName = "http:./get_data?type=temperature";

var i=0;
                                            // issue request to server
function sendXMLHttpReq( method, url, async, callback, txt ) {
    var req = false;
                                            // branch for IE/Windows ActiveX version
    if(window.ActiveXObject) {
        try {
            req = new ActiveXObject("Msxml2.XMLHTTP");
        } catch(e) {
            try {
                req = new ActiveXObject("Microsoft.XMLHTTP");
            } catch(e) {
                req = false;
            }
        }
                                            // branch for native XMLHttpRequest object
    } else if( window.XMLHttpRequest ) {
        try {
            req = new XMLHttpRequest();
        } catch(e) {
            req = false;
        }
    }
    if( req ) {
        req.open( method, url, async );
                                            // cancel cache on IE
        req.setRequestHeader("If-Modified-Since","Thu, 01 Jun 1970 00:00:00 GMT");
        if ( callback ) {
            req.onreadystatechange = 
                function() {                // when successfully completed
                    if ( (req.readyState == 4) && (req.status == 200) ) {
                                            // hand the data to callback
                        callback( req.responseText );
                    }
                }
        }
        req.send( txt );
    }
}

function show_in_browser(temp) {
document.getElementById('div1').innerHTML+=(temp + "<br>");
}

function read_temperature() {
    for(i=0; i<10000; i++){
        sendXMLHttpReq( "GET", CGI_funcName, true, show_in_browser, " " );
    }
}

// -->
</script>
</head>

<body onload="read_temperature()">

<form id="div1" action="">
</form>


</body>
</html>

Editado por johnwww
Link para o comentário
Compartilhar em outros sites

  • 0

John eu jamais iria pensar no modo assíncrono, ainda bem que conseguiu solucionar rsrsrs.

Me tira uma dúvida cara, eu não vou conseguir te ajudar enquanto eu não conseguir esclarecer ela.

Para que tantas iterações ? Por que 10.000, 30.000, 40.000 ? Isso ainda não está claro pra mim. O que é o retorno do seu Ajax?

Não se faz tanta requisição assim em Ajax. Pelo menos eu nunca vi... O Ajax é usado em um evento ou num load de algum arquivo de informação, mas isso o que está fazendo está me fugindo da compreensão.

Pode esquecer essas iterações tão altas...eu estou com a impressão de que está tentando solucionar um problema simples da maneira mais complicada.

Me esclarece por favor.

Akelabrasssssss.

Link para o comentário
Compartilhar em outros sites

  • 0

Concordo com você, acho que deve existir uma solução mais fácil, mas como estou começando nesta área de desenvolvimento web, é normal, hehe.

Tenho um kit de desenvolvimento web, que é microcontrolado e tem 128KB para criação de páginas. Pode parecer pouco espaço, mas para um microcontrolador é muito espaço. Esse kit, lê temperaturas de um sensor, armazena essas temperaturas com data e hora em um pendrive num arquivo .txt, linha por linha a cada 3 segundos. Só tenho como acessar esse arquivo .txt linha por linha para leitura ou escrita. Esse projeto, ficará aquisitando temperaturas direto, e a cada dia, terá um arquivo de log .txt novo (um arquivo por dia). A idéia inicial, era que o usuário digitaria o dia desejado, e faria o dowload do arquivo correspondente talvez via ftp. O problema é que esse arquivo criado no pendrive, terá uns 3MB, e não caberá no espaço do microcontrolador que tem 128KB, e não tem como ser acessado normalmente no pendrive, apenas linha por linha. O download do arquivo seria a melhor opção, mas não sei como implementá-lo nessas condições. Pensei em vez do download, criar uma página, e escrever nela linha por linha do arquivo, e ela seria gerada no computador do cliente, mas quando eu escrevo a segunda linha, ela apaga a primeira. Então surgiu o ajax, que escreve as linhas sem apagar as anteriores, e o loop alto, já que o arquivo de log terá 28 800 entradas aproximadamente. Essa dificuldades todas são porque o sistema é muito limitado. Se você tiver uma idéia mais prática, fico muito agradecido.

Muito obrigado pela atenção.

Editado por johnwww
Link para o comentário
Compartilhar em outros sites

  • 0

Acho que entendi john, mas eu não tenho uma boa notícia. Como não estou em contato com o código o tempo todo, nem com o cgi será muito difícil te ajudar....

Ainda não sei se entendi direito, mas pelo que você diz o arquivo a ser baixado precisa ser baixado todo, não apenas um fragmento. Eu tenho a impressão de que o problema não seja no javascript e sim no Cgi. Da forma que eu entendi, eu solucionaria seu problema do mesmo jeito que alguns sites que disponibilizam arquivos pra download fazem.

Como? Exibindo um número X de entradas numa página, e criaria links para outras entradas.

Do mesmo jeito que o fórum faz quando um post tem muitas respostas. Ele precisa ser baixado todo do servidor, porém, não pode ser exibido em uma página só, senão o navegador trava mesmo. Então, na programação em php, o cara faz mostrar, sei lá, 10 posts por página, e mostra em cima dos posts os links para baixar os demais.

De forma análoga, você poderia exibir, por exemplo, 10 temperaturas numa página, e faria com que o cgi retornasse, além das temperaturas, os links para o restante.

Olha só o que eu fiz para um projeto meu e de um amigo meu:

http://archives-project-desk.110mb.com/dir/Wallpapers/Walls.php?q=5&pg=1&n=WinVista

Eu fiz esse php para abrir x imagens por página. Por que meu amigo postou várias imagens e queriamos mostrar todas, porém, não todas ao mesmo tempo.

Se você mudar o valor da variável q do link, vai perceber que o número de links mudará assim como a quantidade de imagens, "q" nesse script é o número de imagens que eu quero exibir por página. Vai testando alguns valores de "q" e você notará que o script é inteligente e criará tantos links quanto precisar. E eu requisito uma vez só a cada click através de Ajax, apenas uma vez.

Eu estou viajando? Será que fez algum sentido o que eu disse para a solução do seu problema?

Kelabrassssss

Link para o comentário
Compartilhar em outros sites

  • 0

Faz todo o sentido. Eu não postei o CGI, porque o meu webserver é um microcontrolador, não um computador, ou próximo disso. O CGI é emulado pelo microcontrolador, e não é programado com as linguagens apropriadas para o propósito.

Gostei muito da sua idéia de separar em fragmentos, e vou tentar aplicar ao meu projeto. No momento estou tentando entender como seu código funciona. Aquela idéia do download você acha inviável?

Obrigado pela idéia

Editado por johnwww
Link para o comentário
Compartilhar em outros sites

  • 0

Então cara, o que está tentando fazer não deve ser muito facil não rsrsrs.

Achou que a rapadura era mole ?!!?!

O algoritmo do meu código é esse:

http://scriptbrasil.com.br/forum/index.php?showtopic=111765

É o mesmo algoritmo que usei para o php, com algumas pequenas mudanças. Se não conseguir entender me avise que te explico com detalhes.

Quanto ao download, vai depender do que você quer. Talvez seja uma alternativa...ainda não pensei sobre isso cara sinceramente, você está interessado em fazer por downloads? Se estiver, eu tentarei pensar num jeito de fazer isso. A forma mais complicada mesmo é solução que eu já propus.

Cara, está fazendo isso com microcontrolador? Tipo, você usa alguma linguagem pra funcionar essas leituras ? Tipo, assembler, vhdl??? Isso ae já é coisa pra maluco rsrsrs.

Kelabrassss

Link para o comentário
Compartilhar em outros sites

  • 0

A linguagem que estou usando no microcontrolador é C, o compilador é o KEIL. Muito boa sua idéia de fragmentar o arquivo de log para mostrá-lo na tela. Estou estudando se devo flexibilizar o número de entradas por página, ou deixar um número fixo, pois percebi que o desempenho do computador influencia no travar ou não, com alto número de entradas por página. Também tem um incoveniente, quando coloco um número alto de entradas por página, as entradas na tela não ficam sequenciais, como no arquivo de log. Parece que o script faz várias requisições ao mesmo tempo, e as vezes uma requsição mais nova, é atendida antes da mais antiga, consequentemente aparecendo no browser as linhas do arquivo aleatóriamente. Estou analisando essas limitações, e quando tiver mais um progresso te escrevo novamente.

Valeu pela ajuda.

Editado por johnwww
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,3k
    • Posts
      652,6k
×
×
  • Criar Novo...