tadarank afiliados

02 junho, 2006

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

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.

Gostou da dica acima? Então clica nos botões de compartilhamento abaixo e me ajude a dica a subir no Google.

60 comentários:

  1. 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

    ResponderExcluir
  2. ah... eu adicionei a linha no arquivo httpd.conf (pra quem não sabe) hehehe

    ResponderExcluir
  3. Valeu cara, até que enfim consegui consertar os acentos, hehe!

    até

    ResponderExcluir
  4. 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

    ResponderExcluir
  5. 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!

    ResponderExcluir
  6. 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 .

    ResponderExcluir
  7. 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 .

    ResponderExcluir
  8. 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...

    ResponderExcluir
  9. 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.

    ResponderExcluir
  10. It works, keep posting!! :}

    Fabiano Shark

    ResponderExcluir
  11. 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.

    ResponderExcluir
  12. 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?

    ResponderExcluir
  13. @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.

    ResponderExcluir
  14. 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 ?

    ResponderExcluir
  15. Uma coisa não impede outra anônimo.
    E o session_start() não é obrigatório que fique no começo do arquivo.

    ResponderExcluir
  16. 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 ???

    ResponderExcluir
  17. Sempre ajudando Micox, muito obrigado.

    ResponderExcluir
  18. 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

    ResponderExcluir
  19. Eu fiz isso, contudo soh deu certo no firefox no ie continuou o mesmo problema o que eu posso fazer?

    ResponderExcluir
  20. 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.

    ResponderExcluir
  21. 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!!!!

    ResponderExcluir
  22. Valeu... Muito boa essa dica!

    ResponderExcluir
  23. Ae maluco
    Hoje é 30/05/07 e sua dica me ajudou mt. Valeu ai blogueiro, show! parabéns.

    ResponderExcluir
  24. Faltou colocar um ponto e virgula no final do php...
    <php header("Content-Type: text/html; charset=ISO-8859-1",true); ?>

    ResponderExcluir
  25. 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.

    ResponderExcluir
  26. 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

    ResponderExcluir
  27. 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 é

    ResponderExcluir
  28. sem dores de cabeça...

    use esta linha simples:

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

    abraçõs

    ResponderExcluir
  29. 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

    ResponderExcluir
  30. Salvou a lavoura!

    srsrs

    valeu !

    Victor

    ResponderExcluir
  31. 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

    ResponderExcluir
  32. 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&parametro=%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

    ResponderExcluir
  33. 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.

    ResponderExcluir
  34. 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&parametro=%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 "";
    }
    }
    }

    ResponderExcluir
  35. apenas adicionei a meta do html.. e funcionou

    ResponderExcluir
  36. 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"

    ResponderExcluir
  37. Só isso??? Deu certinho! Tava quebrando a cabeça com esses acentos. Valew.. ;)

    ResponderExcluir
  38. Com apenas uma linha... foi demais. Valeu

    ResponderExcluir
  39. 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

    ResponderExcluir
  40. 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.

    ResponderExcluir
  41. 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!

    ResponderExcluir
  42. 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...

    ResponderExcluir
  43. Resolveu meu problema de acentos também. Estou pegando 5 XML remotos e tratando pra gerar uma página de notícias.

    Muito obrigado.

    ResponderExcluir
  44. cara valeu me ajudou bastante!

    ResponderExcluir
  45. nas minha requisições XHR eu tratei meus campos com utf8_decode($campo)... foi a unica coisa que funcionou comigo...

    ResponderExcluir
  46. Como sempre El Micox com a solução rápida, fácil e prática.
    Quando crescer quero ser igual ele. o_O

    ResponderExcluir
  47. Você é o cara.... Muito bom... tava quebrando a cabeça aqui....

    ResponderExcluir
  48. Belo, resolvido.

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

    []'s

    ResponderExcluir
  49. Deu certo cara!!! Muito obrigado pelo post!!! Deus abençoe vc e toda sua família!!!

    ResponderExcluir
  50. Olá amigo, o responseXML no FF 3.5.7 não foi tratado corretamente do UTF-8 para o padrão do meu site(ISO-8859-1), a engine é Mozilla/5.0 (Windows; U; Windows NT 6.1; pt-BR; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7 GTB6.

    Conforme disse é mais uma lenda, ou não.

    ResponderExcluir
  51. Valew mesmo uso firefox aqui e nem assim estava interpretando os acentos e acertei o header como vc falou e os problemas acabram!! Obrigado Amigo!

    ResponderExcluir
  52. Olá, fiquei um dia e meio tentando encontrar uma solução para o auto completar com os dados puxados do sql, utlizando php e jquery, os acentos deixavam os nomes com simbolos, SEA AJUDA CONSERTOU meu código e funcionaou perfeitamente.

    ResponderExcluir
  53. Aew cara, parabéns pelo post. Me ajudou bastante.

    Parabéns pela solução.

    ResponderExcluir
  54. Prezados pesquisadores, a solução se constitue em um conjunto de providências:

    Chamada Ajax:

    $.ajax({
    url : "Ajax_getxxx.asp?Param="+Param,
    success : function (data) {
    window.status = data;
    $("TAG[Id=IdTag]").html(data);

    }
    });

    Script ASP (por exemplo):

    Session.CodePage = 1252
    -
    -
    -
    Response.CharSet = "iso-8859-1"
    Response.AddHeader "Content-Type", "text/html; charset=iso-8859-1"

    Isto porque as scripts ASP trabalham com uma página de código. Os responses com outra.

    ResponderExcluir
  55. Parabéns cara, vc salvou o meu dia, sofri pra achar essa solução.

    Que Deus te abençoe!

    ResponderExcluir
  56. Eu trabalho com JSP. Para resolver eu coloquei <%@ page contentType="text/html; charset=ISO-8859-1" %> na página que é chamada "xmlHttp.open("GET","http://localhost:8080/projetoB/pagina.jsp",true);"

    Obrigado pela ajuda!

    ResponderExcluir
  57. Eta, Micox!

    Funcionou pra mim cara..Valeu ae!

    ResponderExcluir
  58. O que eu andei à procura disto e no fundo é tão simples... Obrigado :)

    ResponderExcluir
  59. Resolveu 100% um problema meu aqui. Muito Obrigado!

    ResponderExcluir

Resultado! Concursos