¿Que onda con UTF-8? Sets de caracteres, la web y Ajax
Objetivo
Al finalizar este artículo, el lector, si logra traducir algo de mi verborrea, será capaz de
- Entender de forma bastante vaga que son las codificaciones de caracteres
- Decir, ¡A,ha!, cuando lea ASCII, ISO-8859-1, Unicode y UTF-8
- Entender como maneja el objeto XMLHttpRequest los set de caracteres en Firefox e IE
- Realizar aplicaciones que manejen de modo adecuado las codificaciones y decodificaciones de UTF-8 a ISO-8859-1 en PHP
Dicho esto, pueden leer el texto
Breve trasfondo histórico de los set de caracteres
ASCII, ISO-8859-1, UNICODE
Uno de los problemas de trabajar en nuestro idioma castellano (y en general en los romances) es el uso de los tildes y la ñ. Hasta inicios de los 90, todo el mundo se ahorraba problemas escribiendo en los formularios TODO EN MAYUSCULAS y dejando a los NUNEZ igual que los NUNEZ. Claro, estabamos bajo el dominio del ASCII, que para los que no sepan, en un estándar que define la asociación entre un patrón digital y un carácter o glifo. En particular, los caracteres (letras y caracteres de control), ocupan 7 bit de información. Por tanto, existen 128 caractéres disponibles.
Si bien ASCII cuenta con caracteres "nacionales", como el tilde, el acento circunflejo y otros, se debían crear los caractéres imprimiendo el carácter original (la a), un retorno de carácter y el caracter nacional encima. Horrible.
Para solucionar esto, llego la norma ISO-8859, que define variados mapas de carácteres para distintos países. El que nosotros ocupamos es el infame ISO-8859-1, o Latin-1, una derivación de ISO 8859-1 (lean el artículo en la Wikipedia para que sepan exactamente la diferencia) que cuenta con caractéres usados comunmente en Albania, Catalán, Danés, Alemán, Inglés, Francés, Finlandés, Islandés, Irlandés, Italiano, Latín, Noruego, Portugués, Escocés, Suizo y, como no, Español.
Si bien este formato es el más extendido en la actualidad, siempre ha estado la inquietud de sacarse de encima todo el lío de los distintos set de caracteres, unificando todo en un único sistema de codificación. Esto lo ha logrado el estándar Unicode, una de cuyas implementaciones, el UTF-8, es la que predomina en GNU/Linux y en la red
UTF-8
UTF-8 (Formato de transformación Unicode de 8 bit) es una codificación de caracteres de largo variable. Usa grupo de bytes para representar el estándar Unicode para la mayoría de los lenguajes del mundo.
¿Cómo funciona? Primero, para los caracteres dentro del rango ASCII, ocupa sólo un byte de información por carácter. Para el resto, se pueden ocupar desde 2 a 4 bytes. Una de las gracias de esta codificación es que siempre el bit más significativo para cada carácter no ASCII es 1, lo cual impide que aparezca en medio de la cadena un byte 0x00, lo cual sería fatal para cualquier aplicación C. Tocando lo práctico, veamos como maneja UTF-8 nuestros caractéres en español. Si tenemos el siguiente texto grabado como UTF-8 (cortesía de SciTe):
A E I O U á é í ó ú ñ
Podemos ver, a simple vista, que hay 11 letras y 10 retornos de carro(estoy en Linux, folks), lo cual nos da un total de 21 caracteres. Ahora bien, la cuenta de bytes me dice que hay ¡27! bytes utilizados. ¿Cómo es eso?
Lo más sencillo, para tener un rápido vistazo, es ver el archivo con ISO-8859-1, cortesía de Jedit:
A E I O U ?¡ ?© ? ?³ ?º ?±
Como se puede observar, los 5 primeros caractéres se representan por un sólo byte, que corresponde exactamente a la descripción ASCII, por lo cual se ven igual en ISO-8859-1. Ahora bien, los caracteres con tilde y la ñ son representados por 2 bytes, los cuales no tienen nada que ver con la codificación ISO-8859-1, por lo cual se ven muy raros. Veamos lo que nos dice un editor hexadecimal:
41 0A 45 0A 49 0A 4F 0A 55 0A C3 A1 0A C3 A9 0A C3 AD 0A C3 B3 0A C3 BA 0A C3 B1
C3, por si acaso, es 11000011 en binario, así como A1 es 10100001. Para caracteres de dos a cuatro bytes, el primer byte será 110xxxxx, 1110xxxx o 11110xxx si el caracter ocupa 2,3 o 4 bytes, respectivamente, mientras que el resto va como 10xxxxxx
En resumen....
Existen diferentes formas de codificar los caracteres. Las más comunes en el habla hispana son el ISO-8859-1 y el UTF-8, siendo esta la forma preferida por su compatibilidad a futuro. Si una se equivoca en la codificación, las cosas se ven muy feas
Los caracteres en la web
En las páginas Web.
Para especificar el set de caracteres a utilizar tanto en HTML como en XHTML, se utiliza en el de la página el código
- <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
Para UTF-8, o
- <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
Para ISO-8859-1 (Latin-1).
Como es de suponer, todo el contenido de la página tiene que estar EFECTIVAMENTE escrito en ese set de caracteres. Para hacer una prueba rápida, si están en Firefox, vayan a View->Character Encoding->Western (ISO-8859-1) y verán lo linda que se ve esta página (que está en UTF-8) con el set de caracteres equivocado.
XMLHttpRequest y UTF-8
Ahora viene lo bueno, chiquillos. El objeto XMLHttpRequest, básico para el uso de Ajax, SIEMPRE ocupa UTF-8 para enviar y recibir datos. Punto.
¿Por qué, entonces, muchas de las herramientas para Ajax funcionan extraño con los caracteres?. Revisando la página Comparing escape(), encodeURI(), and encodeURIComponent(), me di cuenta de:
- Si enviamos un contenido por POST, este va a ser enviado siempre por UTF-8, pero si lo envíamos por GET, será codificado en ISO-8859-1 en Mozilla y en UNICODE en IE, usando la función escape
- La función
encodeURIyencodeURIComponent, tanto en IE, como en Mozilla envía la representación UTF-8
Eureka! El error entonces, en el script que tengo de prueba aquí, es que ocupo escape tanto para GET como para POST, lo que hace que se comporte distinto en IE y en Firefox. Lo ideal es usar encodeURIComponent() cuando se envíe el dato por GET y por POST, para mantener siempre UTF-8 como codificación de caracteres y escapar el carácter "&" y "+", que con encodeURI no son codificados
Conclusión
Al utilizar XMLHTTPRequest, se deben enviar los datos por POST y con GET con encodeURIComponent. Si se desea ocupar ISO-8859-1, es un cacho, porque IE va a pasar los valores por GET por UTF-8, en tanto que Mozilla no. En general, mejor usar UTF-8 para todo
Actualización Nº1: Me equivo al recomendar encodeURI. Se debe utilizar encodeURIComponent (gracias, Ignacio).
- 56992 lecturas

Hola,
EStoy usando toxic y todo funciona bien hasta que empiezo a usar ñ,?,á,é,í,ó,ú
No me acepta estos caracteres.
Alguien sabe que puedo hacer??
Víctor!!
Con Ignacio estamos viendo que el principal problema de Ajax es precisamente el uso de caracteres. Los japoneses parecieran ser nuestra principal fuente de referencia en este momento...
Gracias al truco del firefox (no entendia porque estaba esa opción de ver la codificación), y gracias por recordarme la instrucción meta.
Me ha ayudado a acabar un pequeño script php para leer rss de un drupal.
Muchas gracias.
Cualquier cosa, avisa, fermi
Este problema no solo se da en el envío, sino también en la respuesta. Si recibimos algún carácter "raro" como tildes, ?'s , etc, no recibiremos el carácter deseado, alguien sabe algo?
Entonces, cuando escribo el XHTML, debo poner los acutes para los acentos o eñes? o los escribo directamente con acentos y luego pongo el set de caracteres en UTF-8?
A ver. Si tienes un servidor en Apache sobre Debian y no puedes hacer nada con el charset, es mejor ocupar los acutes.
Ahora, lo ideal es desactivar la opción vía .htaccess y grabar con UTF-8, con los encabezados respectivos. Eso es lo que recomienda el estándar, por lo menos.
Bueno este mundo del ajax en nuevo para mi y intento absorver todo lo que puedo lo mas rapido posible en fin es la moda y los programadores nos dejamos llevar por estas cosas la verdad he venido mirando como funciona he incluso consegui una clase en php con la cual puedo interactuar pero me gustaria unas explicaciones mas tecnicas que me permitan enteder todo lo que hay detras de esta tecnologia asi que agradeceria la colaboracion de tod ustedes
Gracias,
La exposición de tu página me ha ahorrado un montón de tiempo buscando el error.
Simplemente estaba probando XMLHttpRequest desde páginas XUL a servidores PHP y no conseguía que los caracteres salieran correctamente. Utilizando encondeURIComponent (y no mezclando UTF-8 con ISO-8859) todo funciona correctamente.
Hola, alguien sabe como puedo generar un mail con java y que al recibirlo con Lotus Notes aparezcan las tildes en vez de '?'.
Gracias.
Hola, sobre el articulo, o esta mal planteado o yo lo he entendido mal.
Porque segun dices, Ajax siempre usa UTF-8 para devolver los datos de una URI pero segun defines UTF-8, tiene letras como á í é ó, que te puedo asegurar que NO muestra correctamente.
Creo que no has puesto el juego de caracteres correcto, aun así he intentado hacer el encodeURIcomponent() pero sigue mostrando mal los acentos :(, y en la meta esta definido como charset=iso-8859-1 como ha de ser, pero no hay manera de que lo muestre bien, para ver de lo que estoy hablando hechaz un vistazo a mi web y dadle a Home.
Saludos!
Bueno, pues yo estoy cogiendo datos de un servidor de mapas los parseo a xml y los transformo en html con xslt. La cuestión es que hago todo esto en utf-8 pero tengo problemas con ciertos carácteres. Yo creo que al final debería recibir como respuesta Ã? en lugar de una supuesta eñe. Pero se da el caso de que cuando intento cargar el tag que recibo con este dato, me da un error javascript y me dice que no existe ese tag. Yo creo que se está recibiendo mal y da error al generar el DOM. Si no no lo entiendo, porque he imprimido la respuesta que le voy a dar al cliente y la tengo completa y bien formada excepto por el Ã?
Cuando no tengo estos caracteres resulta funcionar bien. Además creo que cuando se encuentra con estos, en alguna parte se transforma mal el texto ya que en otros tags que sí recibo resulta que en lugar de < y >, como parte del xml (que venían embebidos en CDATA) recibo los < y >... que HORROR!
No me queda claro en que estás fallando.
El encodeURIcomponent() evita que tengas problemas al enviar datos al servidor. Lo que venga de vuelta, depende de lo que pusiste en tu programación de servidor.
Con respecto al meta, lo que propongo es, precisamente, NO usar iso-8859-1 con Ajax, ya que es difícil controlar que el proceso no falle, especialmente entre navegadores distintos. Ergo, si pruebas todo con IE, lo más probable es que falle algo en Firefox.
Pero es que no tengo otra opción, mi idioma tiene carácteres que no estan en UTF, tengo que usar iso-8859-1 a la fuerza. Como puedo hacer que AJAX los muestre bien?¿
Saludos!
Beldar
Díos mío, escribes en Klingon!
Fuera de bromas, que carácteres estás ocupando que no están en UTF-8? Todo el ISO-8859-1 está incluido....
si tiene problemas en la salida del archivo que genera el ajax solo pongan esto en la primera linea
<?
header('Content-Type: text/xml; charset=ISO-8859-1');
?>
No se el motivo por el cual no aparece el codigo php introducido en mi comentario anterior
entre etiquetas de php pongan esto
header('Content-Type: text/xml; charset=ISO-8859-1');
esto tiene que ir en la primer linea.
si tienen dudas les dejo mi msn eslicarrillo@ejecutivo.com
Hay que tener cuidado con el la solución de Emmanuel. Lo primero, es verificar que el servidor apache no envíe por defecto otro tipo de charset. Lo segundo, es que hay que realizar la decodificación del UTF-8 de los contenidos recibidos. Sigo pensando que es mejor mentalizar que de aquí en adelante es mejor trabajar todo en UTF-8.
Que tal, he tenido el mismo problema con los caracteres especiales desde hace tiempo y creo que esto por fin puede terminar con mis problemas. El ío hasta ahora es el siguiente.
Ya he creado mis bases con utf-8 y toda la información se ha guardado de manera correcta, las '?' son '?' y los '´' tambien lo son. El problema es que cuando yo esta informacion la veo desde Web, me apaecen esos caracteres extraños como los del ejemplo cuando le han dado a ISO-8859-1.
Ya antes habia probado ponerle a mi html en el meta "utf-8", pero los caracteres siguen mostrandose de manera incorrecta. Como bien dijeron aqui, el problema no solo es al enviar información, sino tambien al recibirla. La pregunta es entonces ¿como hacer que tambien esta información sea correctamente desplegada?
Saludos, ojalá puedan ayudarme enviandome información a mi correo.
Puede que sea apache con el default-charset a iso-8859-1. También prueba a enviar un header con header("Content-Type: text/html; charset=utf-8");
Bueno, me puse a revisar que es lo que recibía al pasar los datos con el AJAX y he comprobado que con el encodeURIComponent() ahora los datos si me pasan bien.
He mandado a imprimir el query que armo con PHP y esta perfecto con
SELECT * FROM empresa WHERE razonSocial LIKE 'A FAVOR DEL NI?O%'
Si ese query lo copio y pego en la consola de MySQL me trae los resultados esperados(2 registros). Pero en navegador me dice que no hay coincidencias. Y sigue pasandome lo mismo cuando yo pongo algo como..
SELECT * FROM empresa WHERE razonSocial LIKE 'A FAVOR DEL NI%'
El servidor si me regresa los 2 registros , pero de esta manera
A FAVOR DEL NI??O, I.A.P.
Se me sigue haciendo problema de comunicacion entre el navegador y el servidor de BD. Me gustaria saber como puedo hacer que los datos que mas abajo me aparecen en latin1, pudieran estar en utf-8 tambien.(He instalado todo via aptitude en una maquina con ubuntu)
dandole a MySQL un /s
Server characterset: latin1
Db characterset: utf8
Client characterset: latin1
Conn. characterset: latin1
Saludos y gracias de antemanos por todo el aprendizaje.
No me queda claro a que te refieres con servidor. ¿Es el de base de datos, o el apache?
La cosa, por lo visto, es que en la base de datos lo tienes todo como UTF-8, y al mostrar en el cliente (que supongo es el explorer), aparece todo en Latin-1.
Como estás ocupando Debian, revisa tu httpd.conf por el DefaultCharset. Si ocupas MySQL 4.1, te puede ser útil enviar un query con
set CHARACTER SET utf8Exactamente eso es lo que yo necesito.
Si observamos,en mi servidor MySQL lo unico que tengo puesto a utf-8 es la BD que estoy utilizando, todo lo demas dice latin1 y yo creo que no debo de utilizar demasiado mi lógica para deducir que este es actualmente el unico problema que me queda despues de que en mis programas y en la configuracion de php he dejado todo como utf-8.
El caso es que no encuentro como decirle a MySQL que lea y devuelva todo como utf-8. Yo, como te lo comentaba, instalé mediante aptitude, y he leido que por default MySQL se instala como latin1 latin1_swedish_ci.
My version de MySQL dice asi
Your MySQL connection id is 426 to server version: 5.0.19-Debian_1.dotdeb.1-log
Ya habia leido en otro lado que ponieno (SET NAMES, "uft-8) se cambiaba la configuracion en la conexion actual, pero yo he modificado ya mi conexion para dejarla de esta manera
$conex = mysql_connect("localhost","root","tico123");
$base = mysql_select_db('facturaciontmp', $conex);
$charset = mysql_client_encoding($conex);
printf ("current character set is %s\n", $charset);
mysql_query("mysql_set_charset_name(&mysql, 'utf8')");
$charset = mysql_client_encoding($conex);
printf ("current character set is %s\n", $charset);
Pero en ambos casos la respuesta es latin1. Probando con el SET NAMES me dá lo mismo latin1 para ambos casos.
Podrías decirme que debo hacer para decirle a mi servidor mysql que voy a utilizar utf-8 , estoy casi seguro de que esa es la respuesta final a mi mas que antiguo problema.
P.D. Y no, lo que utilizo es Firefox.
Estás seguro que este código esta bien?
mysql_query("mysql_set_charset_name(&mysql, 'utf8')");No será?
mysql_options(mysql, MYSQL_SET_CHARSET_NAME, "utf8")o
mysql_query($conn,"SET NAMES 'utf8'");Bueno, pues yo creo que tengo el mismo caso de aquel amigo que escribe en Klingon porque aunque mi servidor MySQL sigue teniendo todo en latin1, he terminado instalando el modulo de mysqli para tener acceso a los cambios que necesitaba.
Ya he podido cambiar el juego de caracteres al hacer mi conexion con un
mysqli_set_charset($conex,"utf8");
Y probando a que me diga el juego de caracteres con el comando
mysqli_character_set_name($link);
Me dice que efectivamente el juego está en utf8...
El caso es que sigo obteniendo los mismos resultados, al pasarle el query de la empresa 'A FAVOR DEL NI?O' sigue sin encontrarmela, solo me la encuentra si escribo hasta antes de la ? y me la sigue mostrando en pantalla como un caracter extraño.
Recalcar que ya tengo en apache y en php mis default en utf8 y mi tag de html igualmente. Pero el problema sigue siendo lo que recibe y regresa el servidor mysql vía navegador.
Asi que no me queda mas que esperar que venga el chapulin colorado a salvarme.
Saludos!
Ya no es culpa del MySQL, sino del navegador.
Haz un experimento: Graba en disco un resultado de la base de datos, que tenga algo con acentos o con eñe, tal cual como te lo entregue la base de datos. Si te aparece con UTF-8, el navegador no te está pescando los meta del header, que puede ser, repito, culpa de debian.
Bueno, no entendí muy bien esa parte de que si lo guardado me lo despliega en utf-8, pero lo que si hice fue todo lo demás, desde mi php hice una consulta, las 10 primeras tuplas donde la tercera equivale a mi registro con ?, cada línea la guardé dentro de un archivo de texto en mi disco duro y al abrirlo los datos estan todos correctos, la tercera línea dice A FAVOR DEL NI?O.
Ya había leído tu artículo donde platicas lo del problema con ubuntu y el AddDefaultCharset y según yo, me aseguré de quitarle esa línea a mi apache.conf, de hecho, practicamente le quité todos los charsets y dejé solo el de utf-8, de hecho en mi info.php me dice claramente que el charset por defecto es el utf-8 porque yo asi lo indiqué en mi archivo php.ini
Bueno, muchas gracias por seguirme ayudando y lamento tanta molestia.Saludos!
Estimado:
No es ninguna molestia el responder a esta consulta. Es más, se presta para un artículo completo de "resolución de problemas" o "troubleshooting".
Ya que la base de datos y PHP se llevan de maravilla, lo único que queda por verificar es el navegador.
¿Estás seguro que no estás haciendo ningún utf8_encode en el PHP?
¿Se ve bien en firefox? Si no es así, es muy simple verificar el encoding en el cual ve la página buscando en View->Character Encoding
¿Estás ocupando AJAX? Si es así, revisa las cabeceras que recibe el objeto XMLHtppRequest.
Bueno, pues sigo revuelto.
Confirmando que debe ser un problema con el navegador...
Sin hacerle nada mas que yo recuerde, ese sitio ya me esta mostrando los datos como deben ser, y la verdad es que de la última vez que habia probado y no me los habia mostrado bien a la fecha, no le habia movido nada en absoluto.
Pues pasé otro de mis proyectos. De la misma manera que con el primero. Pasé el respaldo de mi BD, la convertí a utf-8 usando el comando iconv de linux, monté el respaldo, hice un php que me guardara los primeros 10 registros en un archivo y luego los imprimí en pantalla y una vez mas me imprimió la ? de manera correcta.
Pasé entonces la carpeta con el desarrollo, le cambié los meta a utf-8, le agregué la función encodeURIComponent() a los datos que voy pasando con el AJAX, y resulta que otra vez me muestra la ? con otro caracter. Revisando que es lo que me entregaba el Ajax me doy cuenta de que si esta pasando el caracter de manera correcta ya con el encodeURIComponent(sin él me los pasa con un ?). Pero si mando a imprimir ? Á?Í?? áéóú de manera directa me aparece ? ????? ?????. El navegador esta en utf-8 , y si le digo que me entregue los datos como iso-8859-1 entonces si me los despliega correctamente, pero claro, como en la BD los datos estan en UTF8 no me encuentra ningun resultado.
Tambien ya mandé a imprimir las cabeceras del xmlhttp y lo que me trae es esto:
Date: Mon, 10 Apr 2006 22:38:03 GMT Server: Apache/2.0.54 (Ubuntu) PHP/5.1.2-1.dotdeb.2 X-Powered-By: PHP/5.1.2-1.dotdeb.2 Set-Cookie: PHPSESSID=0l89a76rhmhpkkjr6a1glpkoa3; path=/ Expires: Thu, 19 Nov 1981 08:52:00 GMT Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0 Pragma: no-cache Content-Length: 14 Keep-Alive: timeout=15, max=94 Connection: Keep-Alive Content-Type: text/html;charset=utf-8
Tengo 2 preguntas a todos esto.
1. Seguiré teniendo ese problema del que hacias mención con la configuracion del apache y el DefaultCharset que me los sigue entregando en iso? (insisto en que ya le borré esa linea en mi apache.conf pero quizá no era esa, aunque de todas formas mi info.php me sigue diciendo que el charset por defecto es el utf-8).
2. ¿Porque entonces mi otro proyecto ya está funcionando si en teoria es lo mismo que el nuevo? en realidad esta basado en lo mismo, son practicamente los mismos procesos de busqueda y obedecen a la misma configuracion del servidor?
P.D. Instalé el phpMyAdmin y tambien ahi me está mostrando los datos de manera incorrecta. O sea, si es un problema con el navegador.
Por la cabecera del xmlhttprequest podemos descartar que estés enviado la cabecera incorrecta. Como php lo está haciendo bien, algo debe estar pasando con el navegador; prueba en IE y en Firefox y dime si los resultados son distintos.
Estamos esperando :)
O algo asi se podría decir. Por fin, despues de tanto revisar y revisar que tenia diferente en ambos proyectos y pretender determinar el porque en uno si se veían bien los carateres y en el otro no, revisé mi código del segundo proyecto.
Resulta que antes de leer este tú artículo, habia tenido problemas precisamente con el paso de los caracteres y tuve que armar una función que reemplazara caracteres por el correcto. Ahora que los estoy pasando bien, esa función hace que me los pase a la manera incorrecta.
Una vez que le he quitado dicha función a todos mis scripts, pude decir igual que tú vuoilá.!!
Creo que, si no me equivoco, lo que tuve tuve que hacer fue.
1. Pasar las BD a utf-8 con el comando iconv de linux.
2. Comentar o bien eliminar la linea del apache #AddDefaultCharset.
3. En ambos(Apache y PHP) poner el caracter por defecto en utf-8.
4. Cambiar los tags de html por utf-8.
5. Enviar los datos mediante AJAX utilizando la funcion encodeURIComponent().
Y con esto fue mas que suficiente no importando si mi servidor de base datos esta con latin1.
Amigo, en verdad te agradezco infinitamente, y sé que muchos lo hacen ya. Saludos
jajajaja. Que bueno que hayas resuelto tu problema. Como dije, es para hacer un post sobre que hay que chequear a la hora de traspasar una webapp a UTF-8.
Sería muy bueno que inscribieras tu e-mail en gravatar, para que dejaras de ser un perejilillo, mi estimado :)
Bueno, perdón por la ausencia, con todo el tiempo que me habia tardado en pegarle a la solución tuve que trabajar a marchas forzadas para recuperarlo.
Bueno, por lo pronto ya me he registrado en el sistema, seguro que por ahí me tocará opinar en algun otro de tus interesantes articulos amigo.
Saludos!
Te estaremos esperando, yacatl
Hola!!
Tengo un inconveniente con las tildes, estoy cargando un combo con ajax que es leido desde una base de datos, e utilizado las opciones de php "header('Content-Type: text/xml; charset=ISO-8859-1');", "htmlentities($cadena)", "str_replace()"; en ves de mostrar la vocal con la tilde muestra la letra pero html (á=áé=é...).
Como puedo arreglar este problema???
Gracias.
De partida, recuerda que es conveniente utilizar UTF-8 para todo.
Si quieres utilizar latin1, recuerda hacer utf8_decode de entrada y utf8_encode de salida.
Si esto no te basta, manda el trozo de código en cuestión, para poder analizarlo mejor.
Tengo un escrito que por razónes que no entiendo se codifico o decodifico y no puedo entenderlo y es de vital importancia leerlo, ya que es el diario de un año de mi vida,word me pide que elija una codificación para leerlo pero con ninguna funciona,¿Qué puedo hacer? ¿puedo enviarles el texto y que me ayuden?
Mira, no sé muy bien como se podrá arreglar, pero si te puedo explicar porque te pide el mensaje.
Al no poder reconocer tu archivo como word, lo califica como un archivo de texto. Como no puede saber que codificación de texto tiene, te pide que selecciones alguna de las disponibles. En resumen: el archivo se daño y Word no lo puede leer. Punto.
hola please help me no puedo chatear por q dicen q no tengo java o algo asi como bajo eso? y de donde?
hola please help me no puedo chatear por q dicen q no tengo java o algo asi como bajo eso? y de donde?
Estoy haciendo una aplicación web con acceso a base de datos.
Pero quiero poder exportar toda la base de datos a ficheros XML.
El problema que tengo es que al salvarlo en XML los caracteres como la ? ñ o los acentos nos los puedo luego recuperar.
Y al trabajar con la base de datos (pero ahora no con SQL) sino tirando de ficheros XML.
Los caracteres ya no son validos.
Quien me puede decir como salvar en XML sin tener problemas al recuperarlo luego.
Salu2
Mel
NOTA: Realmente mi problemas son los caracteres en chino, pero con la ñ me vale.
Una pista cuando se tenga problemas con la eñe y MySQL+php+ajax...
Siendo la url: pregunta_al_server.php?attribute=a%C3%B1o (año)
en php:
...
$attribute =utf8_decode($_POST['attribute']);
...
igual yo, de todo este rollo lo unico que quiero es averiguar como hacer que mysql reconozca la ñ en mis queries
en que archivo de mysql lo cambio y que comando puedo usar desde el command line de mysql. A esto es a lo que yo le llamo ir al grano y no bla bla bla.
creo que por las fechas de los post esta discusion esta mas que muerta
Si la informática fuese como la religión, sería cosa de decir "Lo dice el libro sagrado". Lamentablemente, la vida con los computadores no es tan sencilla.
Por ejemplo, en tu caso:
- ¿Con cuál versión de Mysql trabajas?
- ¿Ocupas Windows o Linux?
- ¿Si ocupas windows, tienes bien configurado el tema de los charset?
- ¿Si ocupas Linux, que LC_ALL ocupas? y ¿qué programa de consola ocupas?
- ¿Cómo está configurado tu default-character-set de tu my.cnf? ¿Sabes donde está instalado, cierto?
Si me das ese bla,bla, podríamos seguir con otro bla-bla :)
Bueno, parece que después de mucho leer lo único que queda es el encode y decode a nivel de php, o hay alguien que sepa configurar en ajax.setRequestHeader O ajax.send algún parámetro para no tener que formatear campo a campo?.
Un saludo.
La Ñ es la Caña de España.
Excelente respuesta resolvio 100% mi problema y de una manera sencilla, gracias....
Hola:
Muy interesante tu articulo, yo estoy creando una aplicacion con mysql, tomcat 6 y jsp el problema es las ñ y los tildes ya configure la base de datos que acepte puros latin1, los jsp con el <%@ page content type="txt/html"; charset=iso-8859-1"; %>
Igual cree la base de datos con character set latin1 collate latin1_spanish_ci, y cada tabla de la misma manera pero sigue sin funcionar.
Pero sigue apareciendome caracteres rarossss ya no se que hacer no se como configurar el tomcat para q tome los caracteres con acentos, que hago ayudaaaaaaaaa por favor!!!!!!!!!!!!!!!!
Bueno yo he tenido ese problema con ajax usando protoype y he logrado solucionarlo usando una función como
function replaceHTML(cadena){
cadena = cadena.replace(/Á/g, "Á");
cadena = cadena.replace(/É/g, "É");
cadena = cadena.replace(/Í/g, "Í");
cadena = cadena.replace(/Ó/g, "Ó");
cadena = cadena.replace(/Ú/g, "Ú");
cadena = cadena.replace(/á/g, "á");
cadena = cadena.replace(/é/g, "é");
cadena = cadena.replace(/í/g, "í");
cadena = cadena.replace(/ó/g, "ó");
cadena = cadena.replace(/ú/g, "ú");
cadena = cadena.replace(/Ñ/g, "Ñ");
cadena = cadena.replace(/ñ/g, "ñ");
return cadena;
}
a partir de esto he hecho una pequeña modificación a la libreria y funciona bien.
Bueno yo he tenido ese problema con ajax usando protoype y he logrado solucionarlo usando una función para el texto que se va a enviar
reemplazando los caracteres por su version ascii
function replaceHTML(cadena){
cadena = cadena.replace(/Á/g, "Á");
cadena = cadena.replace(/É/g, "É");
cadena = cadena.replace(/Í/g, "Í");
cadena = cadena.replace(/Ó/g, "Ó");
cadena = cadena.replace(/Ú/g, "Ú");
cadena = cadena.replace(/á/g, "á");
cadena = cadena.replace(/é/g, "é");
cadena = cadena.replace(/í/g, "í");
cadena = cadena.replace(/ó/g, "ó");
cadena = cadena.replace(/ú/g, "ú");
cadena = cadena.replace(/Ñ/g, "Ñ");
cadena = cadena.replace(/ñ/g, "ñ");
return cadena;
}
a partir de esto he hecho una pequeña modificación a la libreria y funciona bien.
(me parece que por ser este un comentario html los caracter van a salir tal cual como se verían en html así que es cuestión de reemplazar estos por su versión.
Estás flipao. ¿Cómo va a haber caracteres que estén en iso-8859-1 pero no en utf-8?
Vale, tenia este problema en mis sitio y pude solucionarlo con el procedimiento que refieres, pero a mi me sucedia que era el IE (Versión 6) el que enviaba el grupo de caracteres en Latin, con el IE7 no tuve ningún inconveniente.
muy buena la informacion pude solucionar mis problemas en mi page
Obviamente debe estar declarada la cabezera meta charset adecuada..
es indiferente si es UTF8 o ISO8859-1
pues si quiero imprimir Ñ uso : Ñ
o otra funcion de encode@ etc..
para ello hay funciones predefinidas en PHP
y eso es aconsejable siempre hacerlo para no tener dolores de cabeza.. que se ven simbolos raros.
PEEEEEEERO el problema viene cuando tengo un form de busqueda:
ecribo niña .... Click en buscar.
el navegador envia(dependiendo FF o IE)
Fierefox: niña ñ=ñ
Explorer: ni%C3%B1a %C3=Ã %B1=±
Y Yo quiero buscar en una Base de datos mySQL la palabra 'niña'
SELECT alumno WHERE nombre = 'niña' .......... error
SELECT alumno WHERE nombre = 'ni%F1a' .......... error
SOLUCIONES ??
Arreglar la cadena antes de enviarla
encodeURIComponent(form.texto.value);
encodeURIComponent('niña');
y luego llamar al metodo form.send
Claro que despues de recibirla en el script PHP
hay que volver la cadena a su forma original
utf8_decode($_GET['nombre'])
esta es la manera de hacer viajar una niña por la red y que no le quiten y lo mas importante No le Metan nada por el camino.
Claro que viene el problema mayor:
la niña se envio,
la niña llego,
pero resulta que en la BD no hay niña sino niña
y eso es otra leccion: Como convertir una niña en mujer
Buenas
Estoy haciendo una aplicacion que llama muestra datos contenidos en una bbdd, pero al imprimirlos por pantalla, las ñ aparecen como un rombo negro con un interrogante en su interior.
Nunca me habia pasado esto, hasta que he empezado a usar ajax. El tema es que, en un principio, pensaba que era por estar usando ajax, pero es que ahora me aparace no solo con lo que llamo desde ajax, sino con lo que imprimo directamente con php, es mas, incluso lo que imprimo desde html.
He cambiado los charset de las cabeceras, he cambiado las codificaciones de caracteres de los navegadores, he cambiado los charset de la base de datos, y ya no se que hacer (me queda echarme la soga al cuello)
Estoy usando mac, y me ocurre lo mismo usando Safari y FF, pero lo que me resulta extraño es que, hasta ahora, no me habia pasado nunca.
¿Donde tengo que tocar?
Por cierto, estoy ahora mismito usando UTF-8 en el navegador y la pagina que muestro esta codificada en UTF-8. Pero sigue apareciendo el rombito negro (�) de los webs. Sin embargo, en esta pagina (php.apsique.com) la ñ me aparece correctamente :'(
Este es el tercer post en menos de 5 minutos :P
He probado a poner ambos navegadores con la codificacion 8859-1, resulta que veo correctamente lo que imprimo directamente por pantalla, pero no lo que paso desde ajax.
Me he leido toda la discusion que habeis mantenido aqui (¡¡ desde junio de 2005 !!) pero al final no me ha quedado claro que funcion hay que aplicar.
En mi caso, no envio nada mediante ajax, solo recibo informacion, pero me gustaria saber que y como debo aplicar.
Por ahi, alguien me dijo que usara utf8_encode y utf8_decode, pero me parece que es algo bastante poco practico, ya que es mucha la informacion que tengo que pasar desde la base de datos, y supongo que debe haber una funcion sobre ajax que haga directamente esto. Como no me ha quedado claro como se usa encodeURIComponent, no entiendo para qué sirve.
Seria un detalle si pudieseis explicarmelo ;)
Y el cuarto y ultimo post es...
Pues eso, que si usando 8859-1 en el navegador veo bien el html, entonces por que es mejor usar utf-8, si no me funciona correctamente?
Preguntas:
1.- ¿Estás usando tu propio ambiente de desarrollo o estás trabajando en uno de producción?
2.- ¿Estás trabajando todo en utf-8 o tu página estaba antes en iso-8859-1?
3.- Por lo que parece, estabas trabajando con utf-8 de forma "estática", pero estás enviando iso-8859-1 vía ajax. ¿Qué biblioteca estás ocupando para enviar la info?
Eso por ahora.
1.- ¿Estás usando tu propio ambiente de desarrollo o estás trabajando en uno de producción?
No se a que te refieres exactamente, pero uso dreamweaver para la programacion, y phpMyAdmin para la gestion de la base de datos.
2.- ¿Estás trabajando todo en utf-8 o tu página estaba antes en iso-8859-1?
Hasta ahora todas las paginas estaban codificadas en iso-8859-1, porque es la que pone dreamweaver por defecto, y yo, la verdad, no me habia preocupado por averiguar mas informacion sobre esto.
3.- Por lo que parece, estabas trabajando con utf-8 de forma "estática", pero estás enviando iso-8859-1 vía ajax. ¿Qué biblioteca estás ocupando para enviar la info?
Lo de la biblioteca no lo comprendo :P. En cuanto a lo de utf-8, es lo que te comentaba antes, el set de caracteres que he usado siempre ha sido el iso-8859-1.
Por cierto, para añadir mas info sobre las configuraciones que tengo, el juegos de caracteres de MySQL es UTF-8 Unicode (utf8), y el cotejamiento de las conexiones Mysql es utf_unicode_ci, pero las tablas de la misma, algunas aparecen con un cotejamiento utf_general_ci y otras con latin1_swedish_ci. No se si esto tiene algo que ver, pero yo lo pongo ;)
1.- ¿Estás usando tu propio ambiente de desarrollo o estás trabajando en uno de producción?
No se a que te refieres exactamente, pero uso dreamweaver para la programacion, y phpMyAdmin para la gestion de la base de datos.
Me refería a si trabajabas en tu propio computador o en uno de un hosting
2.- ¿Estás trabajando todo en utf-8 o tu página estaba antes en iso-8859-1?
Hasta ahora todas las paginas estaban codificadas en iso-8859-1, porque es la que pone dreamweaver por defecto, y yo, la verdad, no me habia preocupado por averiguar mas informacion sobre esto.
3.- Por lo que parece, estabas trabajando con utf-8 de forma "estática", pero estás enviando iso-8859-1 vía ajax. ¿Qué biblioteca estás ocupando para enviar la info?
Lo de la biblioteca no lo comprendo :P. En cuanto a lo de utf-8, es lo que te comentaba antes, el set de caracteres que he usado siempre ha sido el iso-8859-1.
Por cierto, para añadir mas info sobre las configuraciones que tengo, el juegos de caracteres de MySQL es UTF-8 Unicode (utf8), y el cotejamiento de las conexiones Mysql es utf_unicode_ci, pero las tablas de la misma, algunas aparecen con un cotejamiento utf_general_ci y otras con latin1_swedish_ci. No se si esto tiene algo que ver, pero yo lo pongo ;)
Ah, ok. Lo que puede estar pasando, entonces, es que en algún punto del camino se está transformado el set de caracteres. Supongo que eso ya lo sabías :P
El truco, ahora, está en detectar en que punto está el problema. Supongo que de la base de datos a html estático no hay problemas, así que el punto de error debe estar o en el envío de php que haces hacia javascript o en la codificación que hace javascript al momento de mostrar el mensaje.
¿Ocupas el objeto HTTPRequest a mano, ocupas jQuery, Sajax u otro tipo de código para hacer el trabajo? Puede que allí tengas el problema.
Si, creo que desde la base de datos no debe haber ningun problema, porque ya he usado Mysql muchas otras veces, sin hacer uso de AJAX, y nunca me habia dado errores de este tipo. A parte, como te comentaba, no solo da este problema trayendo info desde la bbdd, sino que tambien lo hace cuando intento imprimir texto de manera directa (escrito directamente desde html).
Por lo tanto, el error está, sin dudarlo, en la llamada a traves de HTTPRequest, que es lo que estoy utilizando (sin hacer uso de ningun framework).
Ah, entonces ahí está. Recuerda que el objeto HTTPRequest siempre ocupa UTF-8, así que si le envías Latin1 se enreda. Ocupa utf8_encode a la salida de la información, y HTTPRequest debería leer bien tu información.
Lo que yo queria es no tener que usar este tipo de funciones , ya que son muchas las veces que imprimo texto enviado por ajax, y no quiero tener que estar pendiente cada vez que lo hago de tener que usar utf8_encode.
¿Hay alguna manera de aplicar dicha codificacion directamente sobre responseText?¿Hay alguna funcion similar para javascript?
El tema es que las paginas que envio suelen tener texto estatico, y no estan generadas por php, sino solo una pequeña parte de ellas. Por ejemplo, cada pagina tiene un titulo que es estatico, aparece siempre, y si contiene una ñ, o un ¿, o cualquier otro caracter extraño, no le puedo aplicar el uft8_encode, por lo que aparece el @#¢∞¬! rombito negro.
Lo que podrías hacer, aparte de pasar todo a UTF-8 (que no creo que puedas hacer), es crear un script en php que funcione como proxy de las páginas estáticas. Entonces, en vez de pedir la página directamente pides al proxy que la cargue y le aplicas el utf8_encode a la salida.
Linda, gracias viejo aprendí mucho, al fin se lo que significa esas lineas de código que siempre me llamaron la atención y me preguntaba que eran y para que servían.
Buen artículo, me aclaró muchas dudas, por demás creo que tienes un "gazapo" en el párrafo del UTF-8, "...ocupa sólo un bit de información por carácter..." debe ser un byte verdad ?
Muchas gracias por las felicitaciones y aún más gracias por avisarme del error. Ya está corregido.
Gracias, funciona perfecto... un simple codigo y como cambia todo
Graaaaaaaaaaacias!
Después de probar con headers con distintos encodings es justo lo que buscaba!!
La verdad no se si esto se los solucione pero a mi me los solucionó.
En el archivo php que me estaba haciendo el Query en el echo que me entrega la respuesta
puse la codificacion utf8_encode().
while($row = mysql_fetch_row($resp))
{
echo utf8_encode($row[1]."||".$row[2]);
}
asi cuando el ajax me recive el texto lo entrega codificado y reconoce todos los caracteres
Justo lo que buscaba, gracias por el aporte
Enviar un comentario nuevo