terça-feira, abril 04, 2006

Envio de grandes conjuntos de dados com AJAX

Hoje, totalmente por acaso, descobri alguns macetes para envio e recepção de grandes quantidades de dados com AJAX, como por exemplo textos. Estou trabalhando em um sistema que permite que o usuário cadastre pareceres sobre informações do sistema, e estes pareceres não tem limitação de tamanho. O sistema foi implementado com AJAX, para permitir que os pareceres sejam carregados dinâmicamente, e gravados assincronamente. O primeiro problema que tive foi que os textos enviados eram sempre truncados em 4096 bytes. A primeira reação foi verificar se estava enviando os dados via POST ou GET: o correto é enviar por POST, uma vez que GET tem tamanho limitado. Os dados realmente estavam sendo enviados por POST, que a priori não tem limitação alguma. Pesquisando um pouco, descobri que precisava definir um header Content-length com o tamanho do conteúdo do texto, antes de enviar a requisição. O comando correto é
requestObject.open('POST', url, true);
requestObject.setRequestHeader('Content-Type',
                             'application/x-www-form-urlencoded');
if (parameters != null)
    requestObject.setRequestHeader("Content-length",
                                   parameters.length);
requestObject.send(parameters);
Bom, eu não sou um expert do protocolo HTTP, mas a minha explicação seria que de fato o método POST aceita uma quantidade ilimitada de dados, mas por default ele define o tamanho máximo como 4096, para evitar erros. Caso o usuário deseje enviar mais, deve informar o tamanho total. Resolvido este problema, tive um problema semelhante ao ler os dados para exibir na tela. Meu sistema abre uma requisição AJAX, que envia um XML contendo o texto do parecer inserido pelo usuário. Para recuperar o texto, executava o seguinte comando:
var value = decodeURIComponent(
                 root.getElementsByTagName('value')[0].
                                       firstChild.data);
Este código retornava o texto corretamente no IE, mas cortava em 4096 bytes (novamente !) no Firefox. O mais estranho é que tanto no envio quanto na recepção, o XML gerado estava correto. Portanto o problema estava na leitura do CDATA do XML. Fuçando um pouco (desta vez não encontrei nada na internet), descobri que em caso de CDATA com mais de 4096 bytes, o DOM do Firefox considera que a tag value possui mais de um nó filho, cada um com no máximo 4K. Assim, o código correto para obter o texto em ambos os navegadores é
for(var i=0; i i++)
     value += decodeURIComponent(
                     root.getElementsByTagName('value')[0]
                           .childNodes[i].data);

0 Comments:

Postar um comentário

Links to this post:

Criar um link

<< Home