domingo, 24 de maio de 2009

Caracteres especiais e charsets encodes utilizando Ajax

Em todas as empresas e projetos que já participei, sempre que se fala em codificação de caracteres não se tem uma resposta exata de bate e pronto.
Gerando sempre aquele toró de palpites sobre o assunto e alguns causos já vivenciados. Mas de fato o que fazer quando preparamos toda a nossa lógica bem afinada e tudo funciona bem, e o cliente abre
no browser para testar a aplicação aparecem aqueles indesejáveis caracteres bugado.
Vou falar um pouco da minha experiência nesse assunto e de como resolvo isso quando utilizo Ajax + PHP.

Em primeiro lugar vou fazer uma breve explanação sobre tipos de codificação.

Charset encode é a forma como fazemos na computação para informarmos o hardware qual o símbolo que desejamos que seja exibido.
Isso nada mais é, a grosso modo, uma tabela onde temos mapeado um símbolo com um número.

Exemplos da tabela ASCII:

01000000 - @

01000001 - A
01100001 - a

A codificação ASCII define 128 caracteres, preenchendo completamente os sete bits disponíveis. Desses, 33 não são imprimíveis.
A medida que a computação foi se estendendo para os quatro cantos do mundo foi se tornando necessário tabelas com uma maior quantidade de símbolos.

Temos hoje dois principais padrões codificação o ISO-8859-1 (apelidado de Latin1 por algumas aplicações) e o UTF-8.

Ambos padrões prevêem nossos caracteres que chamamos de especiais ou seja os acentuados e o "ç".
O grande problema ocorre quando criamos/editamos um arquivo com uma codificação e tentamos exibi-lo com outra.
Por exemplo, seu eu criar um arquivo utilizando o S.O Windows, com as configurações regionais setadas para o Brasil, este arquivo muito provavelmente será codificado com ISO-8859-1.

Acontece que os desenvolvedores menos experientes nem imaginam que tal arquivo já possua uma codificação, por isso na hora de configurar a forma como ele deve ser exibido informam o primeiro padrão que encontram em algum header html qualquer, como por exemplo

content="text/html; charset=UTF-8"

Isso faz com que o client, no caso o browser, exiba os símbolos baseando-se na tabela UTF-8 e como o simbolo "Á" possui um número diferente em ambas as tabelas visualizamos a renderização de um símbolo diferente daquele que escrevemos quando criamos o arquivo.

Então, ai vão algumas dicas para eliminar os caracteres bugados.


Dica 1.


Verifique se o charset que tu estas setando no header do teu html é igual ao do arquivo.

Dica 2.


Busque ao máximo a utilização de html entities nas label e textos de suas páginas.

http://www.w3schools.com/tags/ref_entities.asp
http://www.w3schools.com/tags/ref_symbols.asp

Dica 3.


Quando os dados são provenientes de um formulário onde o usuário que entra com o texto, existem 2 maneiras, que eu utilizo, para processar esses dados.

Primeiro caso:

method="get" ou "post" sendo enviado diretamente para o script informado no parâmetro action da tag form.
Neste caso é necessário que seja setado o charset do script que processará os dados do form, ou seja o arquivo .php para onde fazemos o post do formulário.
Eu utilizo a function header, passando esse parametro.

header("Content-Type: text/html; charset=ISO-8859-1");

Faço isso no inicio do script que recebe os dados via $_GET ou $_POST

Segundo caso:

Quando postamos os dados do form via Ajax, quase sempre encontramos os indesejáveis caracteres no destino final, seja um banco de dados ou um e-mail, etc.
Para me livrar para sempre de problemas desse tipo, além de os headers corretamente configurados, utilizo outras duas funções, uma para o JavaScritp que faz o Ajax e outra no PHP que processa os dados.

No JavaScript:
Quando busco a informação de um determinado input do form que contenha texto digitado pelo usuário como input type="text" ou textarea, sempre faço assim.

var value1=encodeURIComponent(document.getElementById("field1").value);
var value2=encodeURIComponent(document.getElementById("field2").value);
A barbada aqui é usar a função encodeURIComponent.

E depois que chamarmos o método open do objeto XMLHttpRequest ou ActiveXObject (para IE)
É importante setarmos nosso header também.

objAjax.open("POST",url,true);
objAjax.setRequestHeader("Content-Type", "application/x-www-form-urlencoded; charset=ISO-8859-1");

Monto a query string e envio os dados via post….

E no PHP que recebo assim:

$value1 = utf8_decode($_POST['value1']);
$value2 = utf8_decode($_POST['value2']);

Com essa "proteção" extra não tenho problemas com nenhum tipo de caracter que o usuário digite, o que me permite persistir as Strings no banco, gerar relatórios ou e-mails com os símbolos corretos.

Baita abraço.