Ajax - Acentuação, a solução final - 1 linha de código

Postado por Micox - Náiron J. C. G..

02 Junho, 2006

Nota do Autor após ler o tutorial depois de 2 anos: Este tutorial não presta, contem inverdades e enganos. Nem sempre ele funciona. Talvez ele dê certo pra você.

Atenção: Este artigo trata dos problemas de acentuação na RECUPERAÇÃO de um conteúdo via AJAX e NÃO do envio via métodos GET ou POST. Para o tratamento de problemas no ENVIO, veja esta solução (no sub-capítulo "Recebendo os dados (no PHP)".

Uma análise completa de como se comporta cada navegador nos diferentes tipos de requisição GET/POST, UTF-8/ISO-8859-1 DEVE ser lida aqui no blog do nghorta.

Dúvidas, postem no fórum... Comentários e testes, comentem aqui no blog mesmo.

Explicação:

O XMLHttpRequest, a criança por trás do ajax, trabalha no padrão UTF-8 por default, tanto pra enviar dados quanto pra receber. Isso vem do próprio browser mesmo. Nos primórdios da internet, o Tim Berners-Lee ainda não estava tão preocupado com a internacionalização do HTML. Este esforço só começou a acontecer em novembro de 1995, depois da formação da W3C, onde visavam extender as capacidades do HTML 2 (falarei disso no histórico do HTML que estará presente no meu TCC). Por este motivo o Ajax dá vários problemas com nossos caracteres.

Para tentar resolver este problema, já ví muitas viagens, que usam gambiarras de encode, escape, etc. nos scripts do lado do servidor (asp, php, jsp, etc). Uma complicação só!!!

Em minhas pesquisas, descobri que a forma correta de renderizar nosso português é simplesmente usando o charset ISO-8859-1 e não o UTF-8. Simples assim. Você deve enviar cabeçalhos pro navegador, informando que você usará ISO-8859-1. Agora é só você configurar seu servidor pra servir ISO-8859-1 por padrão, se você tiver acesso a isto (eu não pesquisei como se faz isso, pesquisem aí quem se interessar) OU indicar o charset no início do seu script server side, com apenas 1 (uma) linha de código!! -- Me perdoem o "servidor pra servir", é que não achei outros termos. :)

"Chega de enrolação mico, e mostra logo comé que faz. Você prometeu que este blog ia ser de coisas práticas..."

O código:

  • ASP:

    <% Response.Charset="ISO-8859-1" %>

  • PHP:

    <?php header("Content-Type: text/html; charset=ISO-8859-1",true) ?>

  • JSP:

    <%@ page contentType="text/html; charset=ISO-8859-1" %>

Lembrando que os códigos devem ser colocados no início de seu script (pra quem tem pouca experiência com a linguagem). Testado com sucesso no IE6 e FF1.5, quem puder testar em outros browsers, ou colocar seu testemunho aqui dizendo se funcionou ou não...

Você também pode tentar usar só a tag META em arquivos HTML simples, mas eu não consegui fazer dar certo, se alguém souber o porque, comenta ae... <META http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">

Ah, dizem as lendas da mozilla.org que o responseXML interpreta corretamente o charset. Ou seja, se você for usar o responseXML, não se preocupe com isso. Eu não testei e não posso opinar sobre o assunto. Se você tiver testado, comente aqui.

<editado data="27/06/06">
Colocando aqui o comentário do Ederson sobre o responseXML (valeu Ederson):

...o responseXML interpreta certo sim (testei no Opera 9 e no Firefox 1,5), exceto no IE. Com a sua linha, até o IE aceitou o charset e mostrou os acentos.
</editado>/

Observações finais:

Gostaria de lembrar que esta solução que encontrei foi para a recuperação da página no servidor e não para o envio de dados via ajax! A melhor solução que eu achei para o envio dos dados na net foi esta aqui (no sub-capítulo "Recebendo os dados (no PHP)". Ah, pode ser que seu problema também esteja sendo gerado pelo banco de dados. Alguns BD's, guardam seus dados apenas em UTF-8, e aí há a perda de caracteres. Verifique isso também se meu código acima não deu retorno.

É isso aí. Como eu já disse: Dúvidas, postem no fórum... Comentários e testes, comentem aqui no blog mesmo.

Marcadores: ,

E-mail Newsletter Feed RSS Resultado! Concursos Shopping Resultado

Não mande dúvidas nos comentários ou no meu e-mail. Mande elas para o fórum de desenvolvedores Webly. Tem mais gente lá gabaritada a responder e você não fica dependendo só do mico.


Comenta aí! Não cai o dedo e me incentiva a escrever mais. (49 comentários)





49 Comentários:

Anonymous Reges - nao_sei disse... 05 Junho, 2006 15:47  
Ae Mico...
Essa solução vai ajudar muito pra qdo não puder mexer no servidor... show de bola...

Eu resolvi esse problema (tinha acesso ao servidor) adicionando a senguinte linha:
AddDefaultCharset ISO-8859-1
Anonymous nao_sei disse... 06 Junho, 2006 10:30  
ah... eu adicionei a linha no arquivo httpd.conf (pra quem não sabe) hehehe
Anonymous automouse disse... 18 Junho, 2006 11:32  
Valeu cara, até que enfim consegui consertar os acentos, hehe!

até
Anonymous Ederson disse... 25 Junho, 2006 00:59  
Então... só para informar... o responseXML interpreta certo sim (testei no Opera 9 e no Firefox 1,5), exceto no IE. Com a sua linha, até o IE aceitou o charset e mostrou os acentos.

Obrigado
Anonymous Heber disse... 26 Junho, 2006 19:09  
Olá!

Esse post me ajudou pacas! Muitíssimo obrigado!

Estou reconstruindo meu site, e vou fazê-lo todo em AJAX.

Se quiser dar uma olhada na versão atual: www.imaginext.com.br

Abraços e mais uma vez, muiro obrigado!
Anonymous Anônimo disse... 29 Junho, 2006 23:34  
ai Mico nao to conseguindo , fui lá no http e tinha varias linhas e inclusive com o arquivo AddDefaultCharset ISO-8859-1 , deletei tudo e deixei soh ela , mas nao ta adiantando nada .
Anonymous Rafael disse... 29 Junho, 2006 23:39  
no httpd.conf ja tem essa linha .

e eu segui tudo aqui e nao mudou nada , . Por exemplo , Usuário ta saindo Usu?o . me ajudem porfavor .
Blogger Micox disse... 30 Junho, 2006 14:59  
Ae Rafael, fica meio difícil te ajudar já que vc não deixou email de contato para retorno.
Mas qualquer coisa, poste lá no fórum de ajax do imasters: http://forum.imasters.com.br/index.php?showforum=143

té mais...
Anonymous Rafael disse... 30 Junho, 2006 17:59  
Micox eu achei um post fixo em que o Mestre Fyoda colocou uma solução para acentuação no html . coloque lá no post inical a solução .

é o post :

[Dica] Solução final para acentuação no Ajax, Com apenas 1 linha de código: php, asp, jsp.
Anonymous Fabiano Shark disse... 11 Setembro, 2006 10:54  
It works, keep posting!! :}

Fabiano Shark
Anonymous Anônimo disse... 09 Outubro, 2006 09:10  
Bom dia! Tentei utilizar isso no IE mas não deu certo... Uso a versão 6 do IE e no FireFox foi sem o uso de nada... se algum puder me ajudar, meu msn é felipe.benincasa@hotmail.com...
Muito obrigado.
Anonymous Igor (em breve no site em ajax) disse... 10 Outubro, 2006 21:10  
cara olá,
tentei de tudo o que deve ser? os dados do bd ta aaprecendo sem acento mais no bd ta com acento
o que eu faço?
Blogger Micox disse... 11 Outubro, 2006 08:47  
@Igor
Sem um dado de contato ficará difícil eu te ajudar, mas tente ver primeiramente se a codificação do seu banco é a mesma que está usando eu suas aplicações Web.
Anonymous Anônimo disse... 07 Novembro, 2006 12:17  
eu uso em todos os arquivos
session_start() e esse comando precisa ficar na primeira linha, então o header não funciona nesse caso ?
Blogger Micox disse... 07 Novembro, 2006 13:08  
Uma coisa não impede outra anônimo.
E o session_start() não é obrigatório que fique no começo do arquivo.
Anonymous Tom Fonseca disse... 15 Novembro, 2006 22:09  
E se eu usar unicode so site todo?
ex.:
[meta http-equiv="Content-Type" content="text/html; charset=uft-8"]
testei e os acentos fora e vieram sem problemas...

isso pode me trazer algum problema ???
Anonymous cence disse... 17 Novembro, 2006 08:40  
Sempre ajudando Micox, muito obrigado.
Anonymous Anônimo disse... 22 Novembro, 2006 17:15  
Cara estou utilizando ASP.NET com DELPHI, e ja tentei tudo isso.

E infelizmente nada Funcionou.
Pode me ajudar?
Meu e-mail: gladiston.queiroz@confignet.com.br
Blogger Alexandre disse... 24 Novembro, 2006 07:28  
Eu fiz isso, contudo soh deu certo no firefox no ie continuou o mesmo problema o que eu posso fazer?
Blogger Micox disse... 24 Novembro, 2006 07:58  
Deu certo no FF mas não no IE??
Estranho já que a mudança não é a nível de navegador, mas sim ao nível do servidor.
Pode ser problema de cache, tente acessar outro arquivo pra ver se é problema de cache.

Ou então jogue uma pergunta lá no iEvolution.
Anonymous Anônimo disse... 27 Abril, 2007 10:10  
Estou usando uma busca que encontrei na net usando php e ajax, os resultados vinham com o problema nos acentos e, usando apenas a linha do php logo acima resolvi meu problema.
Muito obrigado pela dica!!!!
Blogger Hugo disse... 14 Maio, 2007 16:49  
Valeu... Muito boa essa dica!
Anonymous reche disse... 30 Maio, 2007 14:01  
Ae maluco
Hoje é 30/05/07 e sua dica me ajudou mt. Valeu ai blogueiro, show! parabéns.
Anonymous Vinicius disse... 20 Junho, 2007 09:39  
Faltou colocar um ponto e virgula no final do php...
<php header("Content-Type: text/html; charset=ISO-8859-1",true); ?>
Anonymous JOHNSON disse... 26 Julho, 2007 21:01  
Não consegui retornar com acentuação de nenhuma das formas mostradas.

Caso alguém não tenha conseguido tbm, segue a solução que encontrei.

html = oHTTPRequest.responseText;
obj.innerHTML = char2html(html);


SEGUE O LINK PARA O ".JS"
char2html.js

É só fazer referência ao JS e utilizar a função.
Anonymous Newton Filho disse... 13 Agosto, 2007 16:07  
Para quem não aguenta mais:

asp_utf8.asp

'option explicit

' Simple functions to convert the first 256 characters
' of the Windows character set from and to UTF-8.

' Written by Hans Kalle for Fisz
' http://www.fisz.nl

'IsValidUTF8
' Tells if the string is valid UTF-8 encoded
'Returns:
' true (valid UTF-8)
' false (invalid UTF-8 or not UTF-8 encoded string)
function IsValidUTF8(s)
dim i
dim c
dim n

IsValidUTF8 = false
i = 1
do while i <= len(s)
c = asc(mid(s,i,1))
if c and &H80 then
n = 1
do while i + n < len(s)
if (asc(mid(s,i+n,1)) and &HC0) <> &H80 then
exit do
end if
n = n + 1
loop
select case n
case 1
exit function
case 2
if (c and &HE0) <> &HC0 then
exit function
end if
case 3
if (c and &HF0) <> &HE0 then
exit function
end if
case 4
if (c and &HF8) <> &HF0 then
exit function
end if
case else
exit function
end select
i = i + n
else
i = i + 1
end if
loop
IsValidUTF8 = true
end function

'DecodeUTF8
' Decodes a UTF-8 string to the Windows character set
' Non-convertable characters are replace by an upside
' down question mark.
'Returns:
' A Windows string
function DecodeUTF8(s)
dim i
dim c
dim n

i = 1
do while i <= len(s)
c = asc(mid(s,i,1))
if c and &H80 then
n = 1
do while i + n < len(s)
if (asc(mid(s,i+n,1)) and &HC0) <> &H80 then
exit do
end if
n = n + 1
loop
if n = 2 and ((c and &HE0) = &HC0) then
c = asc(mid(s,i+1,1)) + &H40 * (c and &H01)
else
c = 191
end if
s = left(s,i-1) + chr(c) + mid(s,i+n)
end if
i = i + 1
loop
DecodeUTF8 = s
end function

'EncodeUTF8
' Encodes a Windows string in UTF-8
'Returns:
' A UTF-8 encoded string
function EncodeUTF8(s)
dim i
dim c

i = 1
do while i <= len(s)
c = asc(mid(s,i,1))
if c >= &H80 then
s = left(s,i-1) + chr(&HC2 + ((c and &H40) / &H40)) + chr(c and &HBF) + mid(s,i+1)
i = i + 1
end if
i = i + 1
loop
EncodeUTF8 = s
end function
Blogger Micox - Náiron J. C. G. disse... 30 Agosto, 2007 10:00  
Valeu pela contribuição Newton! :)
Blogger Isaac Nathan disse... 06 Setembro, 2007 00:56  
cara, to usando essa alternativa de colocar o header(...

mas quando vou ver a pagina php ela me retorna com esses caracteres bem no inicio do código: 

tanto abrindo diretamente a pagina quanto por ajax apresenta esse erro aí
realmente não sei o que é
Anonymous Max disse... 10 Setembro, 2007 08:44  
sem dores de cabeça...

use esta linha simples:

$nome=mb_convert_encoding($_REQUEST[nome],"iso-8859-1","utf-8");

abraçõs
Blogger diron disse... 28 Setembro, 2007 09:03  
Max blz cara deu certo....
mb_convert_encoding esta função do php resolve o problema..
to usando xajax e tentei todas as alternativa e não conseguia.. esta função foi a soluão
t+ abração..
muito bom o forum
Anonymous Victor disse... 01 Novembro, 2007 10:08  
Salvou a lavoura!

srsrs

valeu !

Victor
Blogger fabimspank6 disse... 20 Novembro, 2007 09:13  
Opa e are rapaziada alguem podia me passar como configurar os tipos de dados do servidor como o
[ISO-8859-1 ou uft-8]

Este problema comos acentos esta foda uhaua valeu hein ...

fabimspank6@hotmail.com
Anonymous San Portnoy disse... 08 Dezembro, 2007 13:40  
Bem, tenho outra solução que consiste em não fazer alterações em níveis de cliente e nem em server scripts. Eu simplesmente uso uma função do Prototype ($H), que faz um Hash dos parametros e os mandam codificados em HTML, desta forma, conseguimos pegar quaisquer caracteres em todas as plataformas... observem:

javascript:

function GerarFiltro(){
//escreve dica da pagina
ExibirDica("Filtrando dados para o grid de combustíveis. Aguarde...");
var Grid = true;
var Texto = $('txtFiltro').value;
var Qtde = $('selQtde').value;

var parametro = $H({getFiltro: Grid, parametro: Texto, qtde : Qtde }).toQueryString();
// var parametro = $('txtFiltro').value;
// var qtde = $('selQtde').value;

//Zerar a tabela
limpaResultado();
//Resgata combustiveis
createXMLHttpRequest();
xmlHttp.onreadystatechange = hscGerarCombustiveis;
xmlHttp.open("GET","?"+ parametro, true);
xmlHttp.send(null);
}

Ao digitarmos "álcool" no $('txtFiltro'), temos depois a seguinte querystring:

"getFiltro=true¶metro=%C3%A1lcool&qtde=10"

Esta queryString é reconhecida por qquer navegador e também em quaisquer linguagem, no exemplo eu usei C# para lê-la, conforme exemplo:

private string IDCombustivel
{
get
{
if (Request.QueryString["id"] != null && Request.QueryString["id"].ToString() != "")
{
return Request.QueryString["id"].ToString();
}
else
{
return "";
}
}
}


Bem espero ter ajudado, qquer coisa meu email é: sanportnoy@gmail.com

Até mais...
San
Blogger Micox - Náiron J. C. G. disse... 10 Dezembro, 2007 07:57  
Opa, valeu pela contribuição san.
Mas veja que o que eu digo aqui é com relação a receber os dados corretamente no lado do cliente e não receber corretamente no lado do servidor.
Té mais.
Anonymous San Portnoy disse... 16 Dezembro, 2007 10:47  
Versão Corrigida, acertando o parametro do lado Servidor, conforme o Micox falou. Desculpem a navalhada...rs

javascript:

function GerarFiltro(){
//escreve dica da pagina
ExibirDica("Filtrando dados para o grid de combustíveis. Aguarde...");
var Grid = true;
var Texto = $('txtFiltro').value;
var Qtde = $('selQtde').value;

var parametro = $H({getFiltro: Grid, parametro: Texto, qtde : Qtde }).toQueryString();
// var parametro = $('txtFiltro').value;
// var qtde = $('selQtde').value;

//Zerar a tabela
limpaResultado();
//Resgata combustiveis
createXMLHttpRequest();
xmlHttp.onreadystatechange = hscGerarCombustiveis;
xmlHttp.open("GET","?"+ parametro, true);
xmlHttp.send(null);
}

Ao digitarmos "álcool" no $('txtFiltro'), temos depois a seguinte querystring:

"getFiltro=true¶metro=%C3%A1lcool&qtde=10"

Esta queryString é reconhecida por qquer navegador e também em quaisquer linguagem, no exemplo eu usei C# para lê-la, conforme exemplo:

private string _texto
{
get
{
if (Request.QueryString["Texto "] != null && Request.QueryString["Texto "].ToString() != "")
{
return Request.QueryString["Texto "].ToString();
}
else
{
return "";
}
}
}
Blogger Galileujr disse... 14 Janeiro, 2008 12:44  
apenas adicionei a meta do html.. e funcionou
Anonymous Anônimo disse... 25 Abril, 2008 10:27  
Ja tentei usar com response.charset mas não funcionou no ie6, a saida no meu caso para acentuação foi :

Response.ContentType = "text/html; charset=ISO-8859-1"
Anonymous Anônimo disse... 26 Maio, 2008 09:58  
Só isso??? Deu certinho! Tava quebrando a cabeça com esses acentos. Valew.. ;)
Anonymous Pedro G Castro disse... 13 Junho, 2008 13:30  
Com apenas uma linha... foi demais. Valeu
Anonymous Anônimo disse... 27 Junho, 2008 09:36  
Cara não consegui resolver isso, tenho um formulario que envia a validação para um arquivo externo que insere no banco e retorna a nova variavel para o formulário, porém quando insere transforna nos caracteres especiais e não em acentos comuns, onde estou errando, vlw
Anonymous Anônimo disse... 27 Junho, 2008 13:39  
bem como diz o ditado, se vc n pode contra junte-se ao inimigo, meta http-equiv="Content-Type" content="text/html; charset=UTF-8"
inseri isso e ele apresenta certim mas salva no banco com os caracteres especial, funciona ... se está correto ou não é outra coisa, mas vlw msm assim.
Anonymous Nano disse... 23 Julho, 2008 19:55  
comigo nada disso funcionou, no entanto consegui resolver o problema adicionando esta linha:

xmlHttp.overrideMimeType('text/html; charset=iso-8859-1');

antes do

xmlHttp.open("POST",url,false);

Espero que isto sirva a outros, uma vez que levei algum tempo até encontrar a solução!
Blogger Cristiano Coqueiro disse... 18 Novembro, 2008 09:39  
Cara, muito bom, eu tenho um calendario na Intranet da empresa que trabalho e ele busca os feriados em um banco de Dados MYSQL através de um programa PHP, e eu tinha um problema com as datas que continham acentos....sua solução resolveu o meu problema...
Anonymous Gabriel Furini disse... 19 Dezembro, 2008 13:58  
Resolveu meu problema de acentos também. Estou pegando 5 XML remotos e tratando pra gerar uma página de notícias.

Muito obrigado.
Anonymous ismael andres disse... 27 Dezembro, 2008 08:30  
cara valeu me ajudou bastante!
Anonymous Alexandre Afonso disse... 27 Dezembro, 2008 15:30  
nas minha requisições XHR eu tratei meus campos com utf8_decode($campo)... foi a unica coisa que funcionou comigo...
Anonymous Danilo Oliveira disse... 06 Janeiro, 2009 14:12  
Como sempre El Micox com a solução rápida, fácil e prática.
Quando crescer quero ser igual ele. o_O
Blogger Eder Pardeiro disse... 20 Janeiro, 2009 12:01  
Você é o cara.... Muito bom... tava quebrando a cabeça aqui....
Anonymous Anônimo disse... 11 Maio, 2009 10:14  
Belo, resolvido.

Não é toa que ta no topo do Google, hehe !

[]'s

Escreva seu comentário (Leia abaixo).

Deixe seu email se quiser resposta por email também, pois o sistema de comentários do Blogger não me informa :( ... Ah, também pode deixar o endereço do seu blog ou site no comentário.
Já estou em outro sistema de blog melhor (wordpress). Se quiser comentar lá também :)
Dúvidas, só no fórum Webly.

Links para este post:

<< Ir à página principal e ver as novas postagens.

El Micox - Alguns direitos resevados - Licença Creative Commons

Veja! Este é apenas um espelho do blog real elmicox.com. Assinando aqui, na verdade você está assinando lá.