entre Desarrolladores

Recibe ayuda de expertos

Registrate y pregunta

Es gratis y fácil

Recibe respuestas

Respuestas, votos y comentarios

Vota y selecciona respuestas

Recibe puntos, vota y da la solución

Pregunta

3votos

Definir codificación de caracteres javascript+php

Hola.
No logro definir el charset correspondiente en mi formulario php+js+html!!

En el head html agrego una línea:

<meta content="text/html; charset=UTF-8" http-equiv="content-type"> 

También he intentado agregando charset al llamar al script:

<script src="ajax.js" charset="UTF-8"></script>

Pero sigue el error:
(imagen que no carga removida)

2 Respuestas

1voto

top21tk Puntos2090

La solución la encontré agregando:

mysql_query("SET NAMES utf8");

antes de la consulta sql.

Es decir, defino que la consulta devuelva caracteres UTF-8

Todo el merito a Leonardo-Tadei

2votos

Leonardo-Tadei Puntos227320

Hola Nico,

lo que te está pasando es que el script PHP que es llamado vía AJAX no está devolviendo los caracteres en UTF-8.

Tené en cuenta que la llamada vía AJAX es completaemnte independiente del CHARSET definido en el llamador; dicho en otras palabras, son dos script PHP independientes uno de otro.

En tu caso, al estar devolviendo un select HTML no tenés como poner cabeceras indicando que el charset es UTF-8 (a diferencia de si devolvieras una página HTML completa o un XML, y el default del servidor web que usás debe estar devolviendo un juego de caracteres diferente.

Lo podés solucionar agregando al script que es llamado vía AJAX las siguientes líneas de código al principio:

<?php
mb_http_output( "UTF-8" );
header( "Content-Type: text/html; charset=".mb_http_output());
..

con esto el script generará una cabecera HTTP con el juego de caracteres UTF-8 siempre y cuando este charset sea soportado por el servidor.

Saludos!

0voto

top21tk comentado

Si la primera línea está bien, debo tener un problema en mi servidor.
Actualmente uso NGINX

0voto

Leonardo-Tadei comentado

Hola Nico,

no entiendo: pusiste estas 2 líneas de código que te paso y te da el mismo error en el juego de caracteres?

0voto

top21tk comentado

Quedó así:
index.php

<?php
mb_http_output( "UTF-8" );
header( "Content-Type: text/html; charset=".mb_http_output());
include 'conexion.php';
?>

Pero no tengo respuesta. Página en vacía...

0voto

Leonardo-Tadei comentado

Hola Nico,

si no veo mal, estás poniendo este código en index.php, que es quien tiene el formulario, pero deberías ponerlo en el script que devuelve las materias y que es llamado vía AJAX.

Relee la respuesta original. Igual es raro que agregar esto te de una respuesta vacía, ya que solo agrega una cabecera HTTP.

Tenés publicado este formulario en algún lugar para que podamos verlo?

0voto

top21tk comentado

No lo tengo publicado. Es un solamente proyecto offline.

Sin embargo, es el mismo ejemplo que vos me pasaste

codigojerry
Comprobé que funciona, pero el original no tenía acentos en los países que sí correspondía.
Detecté el problema en "España".

Es verdad que lo puse en el index.php porque el código que me pasaste comenzaba con

<?php

Ahora lo agregué al script y no da resultado, incluso probando con caracereres UTF-8 e ISO-8859-1
Obtengo la respuesta, se arma el formulario pero siguen mal los caracrteres.

El script queda así:

mb_http_output( "UTF-8" );
header( "Content-Type: text/html; charset=".mb_http_output());

function load(str)
{
var xmlhttp;

if (window.XMLHttpRequest)
  {// code for IE7+, Firefox, Chrome, Opera, Safari
  xmlhttp=new XMLHttpRequest();
  }
else
  {// code for IE6, IE5
  xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
  }
xmlhttp.onreadystatechange=function()
  {
  if (xmlhttp.readyState==4 && xmlhttp.status==200)
    {
    document.getElementById("myDiv").innerHTML=xmlhttp.responseText;
    }
  }
xmlhttp.open("POST","proc.php",true);
xmlhttp.setRequestHeader("Content-type","application/x-www-form-urlencoded");
xmlhttp.send("q="+str);

}

0voto

Leonardo-Tadei comentado

Hola Nico,

el código que te indico poner en la respeusta es PHP pero lo estás poniendo en un JavaScript!

A ver si me explico enumerando lo elementos (sin el código no sé como llama cada uno, pero puedo describirlos):

1) Tenes index.php con el formulario con las carreras y que al seleccionarla deben mostrarse las materias.
2) tenés el JavaScript con el código AJAX que traerá las materias. Este código puede esatr en el propio index.php o en un archivo aparte llamado en la cabecera de index.php.
3) tenés el script PHP que es llamado por el JavaScript de 2) y que devuelve las materias de una carrera solicitada. En el ejemplo del post anterior este script de llama proc.php

El que tiene que iniciar con el código PHP

mb_http_output( "UTF-8" );
header( "Content-Type: text/html; charset=".mb_http_output());

es este script, el PHP que devuelve las materias y que acá es el 3). Con esto le decís al script PHP que genere una cabecera HTTP que defina el juego de caracteres.

Ponel ahí y contanos!

0voto

top21tk comentado

Hola Leo,

Tengo 4 archivos:

  • Index.php
    -conexion.php
    -proc.php
    -ajax.js

El index tiene el encabezado del formulario y llama a ajax.js
ajax.js llama a proc.php

Segun lo que me indicaste, coloqué

mb_http_output( "UTF-8" );
header( "Content-Type: text/html; charset=".mb_http_output());

en el encabezado de proc.php
recibo la respuesta con el mismo error, es decir, el formulario se arma con error de caracteres.

El ejemplo que me diste tiene el mismo error seleccionando Europa y viendo en la lista "España"

Fijate si en tu servidor funciona bien, por favor.

Muchas gracias por tu tiempo.

Abraazo..

0voto

Leonardo-Tadei comentado

Hola Nico,

en el ejemplo, las tablas guardan los textos con charset latin-1. Tus tablas, en qué juego de catacteres la están guardando? Podrías poner por acá un vuelvo de la tabla Carreras (no los datos: la definición de la estructura)?

Tal vez, además de estar enviando una codificación incorrecta, estás guardando los caracteres en una codificación distinta de UTF-8...

0voto

top21tk comentado

Esta es la tabla materias

enter image description here

0voto

Leonardo-Tadei comentado

Hola Nico,

tu tabla almacena los datos en latin1 en vez de en UTF !

Antes de mostrar los datos en proc.php, convertilos a UTF-8:

if (mb_detect_encoding($string) != 'UTF-8') {
    $string = mb_convert_encoding($string,'UTF-8');
}

PD : siempre es más simple usar en TODAS partes usar UTF-8... pero a veces no se peude por almacenamientos heredados

0voto

top21tk comentado

Antes de armar la base de datos leí que UTF-8 utiliza más bits y por tanto acelera el crecimiento de la base de datos, por eso decidí utilizar latin1. Por inexperto :-(

En cuanto a la solución , dónde coloco el if?

Porque en el index captura los planes.

Estos son mis archivos

Muchas gracias.

0voto

Leonardo-Tadei comentado

Hola Nico,

lo miportante es tener, de ser posible, el mismo charset en todas partes. En latin1 se usan 8 bits por cada caracter, al igual que en UTF-8 (por eso el 8). Lo que sí ocupa más es UTF-16, pero todo esto es irrelevante: el almacenamiento es baratísimo!

Respecto a tu código:

en index.php agregá al HEAD:

<meta http-equiv="content-type" content="text/html; charset=UTF-8">

en proc.php hacé los siguientes cambios:

<?php
mb_http_output( "UTF-8" );
header( "Content-Type: text/html; charset=".mb_http_output());

include 'conexion.php';

$q=$_POST['q'];
$con=conexion();
$res=mysql_query("select materias.id, materias.nombre from materias where idplan=".$q."",$con);

echo "<select name=\"materia\">";
while($fila=mysql_fetch_array($res)){

    if (mb_detect_encoding($fila["nombre"]) != 'UTF-8') {
            $fila["nombre"] = mb_convert_encoding($fila["nombre"],'UTF-8');
    }

    echo "<option value=".$fila[id].">".$fila[nombre]."</option>"; 
}
echo "</select><br><input type=\"submit\"></form>";
?>

No estaría demás que te acostumbres a generar código HTML válido! Al menos, pasá el cierre del FORM a INDEX.php y hacé que proc.php solo genere el SELECT.

Saludos!

0voto

top21tk comentado

Gracias leonardo,
La base de datos es una migrada de access 2000, definir el charset fue también otro lío.
Bueno, hice el intento como me indicaste, pero no funcionó.

  1. Agregué a index el charset
  2. Cambié proc.php en las líneas que me indicaste.
  3. Como no funcionó, directamente copié el codigo de proc.php visto mas arriba.

Planes se carga con error y el select de materias directamente no se carga.
Puede ser el servidor?

Muy acertado tu consejo de acostumbrarme a generar html válido

revisando

Vuelvo a leer la pregunta y en realidad lo que necesito es

mostrar correctamente los acentos en el formulario

La solución tal vez no sea forzar a mostrar utf8 en el formulario...

0voto

Leonardo-Tadei comentado

Hola Nico,

acá te dejo el código funcionando: http://leonardo.tadei.com.ar/nico/

Lo podés descargar de: http://leonardo.tadei.com.ar/nico/nico.zip por unos días.

En resumen: hay que usar el mismo juego de catracteres en todas partes. Lo que verás agregado es que los caracteres se convierten a UTF-87 de ser necesario, y luego se pasan por htmlentities para convertirlos a caractares codificados HTML, y aque una página UTF-8 nunca mostrará bien caracteres almacenados en Latin1 (ISO8859-1)

<?php
mb_http_output( "UTF-8" );
header( "Content-Type: text/html; charset=".mb_http_output());
include 'conexion.php';
$q=1;
if(isset($_POST['q'])) {
    $q=$_POST['q'];
}
$con=conexion();
$sql = "select materias.id, materias.nombre from materias where idplan=$q";
$res=mysql_query($sql,$con);

echo "<select name=materia>";
while($fila=mysql_fetch_array($res)){
    if (mb_detect_encoding($fila["nombre"]) != "UTF-8") {
        $fila["nombre"] = mb_convert_encoding($fila["nombre"],"UTF-8");
   }
   $fila["nombre"] = htmlentities($fila["nombre"]);
    echo "<option value=".$fila['id'].">".$fila['nombre']."</option>"; 
}
echo "</select><br><input type=submit></form>";
?>

A veces los manejadores de MySQL te juegan una mala pasada, porque usan su codificación para manipular los datos, y el sitio web puede usar una distinta. Acá nos ha pasado que hasta que no agregamos datos con nuestra propia aplicación, lo que escribíamos a mano en PHPMyAdmin u otros siempre se veía mal.

Verás también que hay corregidos algunos detalles: si ponés tu PHP a trabajar en modo estricto para que reporte todos los errores, advertencias y noticias, verás que hay cosas que pulir en tu código original.

Por último, usá campos VARCHJAR o CHAR en las tablas cuando el texto no requiera más de una línea. Los campos TEXT son muy ineficientes para hacer búsquedas. También tenés que hacer que coincidan el campo id_plan de la tabla Materias con el tipo del id de la tabla Planes: las relaciones funcionan mucho mejor si todo es del mismo tipo.

Saludos cordiales!

0voto

top21tk comentado

Veo que tu ejemplo funciona perfecto

Los archivos que descargué, luego de configurar biebn la conección, no dan resultado.
Es decir, sólo muestra el primer option, como si no pudiera capturar los datos de la tabla.
Revisé todo el código de nuevo y no encontré nada mal.
Evidentemente es otro el problema.
Igualmente gracias por tu tiempo, dejaré en stand by la solución por un tiempo, no te preocupes por buscar más, debe ser algo que no funciona en mi servidor.

Debo atender otras cosas ahora, cuando compruebe mis errores, marco tu respuesta.

Gracias nuevamente...

0voto

Leonardo-Tadei comentado

Pero qué misterio, Nico,
Al no poder acceder a tu código funcionando, no podremos avanzar más por este camino.
Ya nos contarás como sigue esto y qué era lo que pasó.
Saludos!

0voto

top21tk comentado

Hola Leo, Subí el ejemplo original y funciona.
Está en blog21/ajx
Evidentemente es un problema de mi servidor. Ya veremos...
Muy productivos tus aportes.
Muchas gracias


Responde en una nueva respuesta con el link a codigo jerry para marcarlo como respuesta.


0voto

Leonardo-Tadei comentado

Bueno, es un alivio!

Por favor, accede o regístrate para responder a esta pregunta.

Otras Preguntas y Respuestas


...

Bienvenido a entre Desarrolladores, donde puedes realizar preguntas y recibir respuestas de otros miembros de la comunidad.

Conecta