0

Miren lo que me pasa es que estoy regresando un html por json y me llega vacío si dejo de devolverlo por json y lo recibo normal, entonces si llega bien y no se porque o que es el error:

estos son los códigos:

ajax

  function realizaProceso(){
  var parametros = {};
  $.ajax({
    data:  parametros,
    url:   '../controllers/index.php',
    type:  'post',
    dataType: 'json',//esta linea la quito cuando no uso el json
    beforeSend: function () {
    },
    error: function (request, status, error) {
       console.log(3);
         console.log(request);
         console.log(status);
         console.log(error);
          console.log(4);
    },
    success:  function (response) {
      alert("4");

      /*var randomColor = '#'+ ('000000' + Math.floor(Math.random()*16777215).toString(16)).slice(-6);
      $('#resultado').css({
        'background-color' : randomColor,
      });*/
      console.log(response);
      $(".loader").hide();
      $(".carousel-congratulations").html(response.congratulations);
      $(".carousel-birthdays").html(response.birthdays);
      $(".carousel-events").html(response.events);
      window.history.pushState("", "", '/iq/tv');
    }
  });
   $.ajax({
        data:  parametros,
        url:   '../controllers/changeVideo.php?opcion=leer',
        dataType: "json",
        success:  function (response) {
            $(".urlVideo").attr("src", response[1]);
        }
    });

}

este es el controlador o donde se hace la consulta

   <?php
//fecha del dia de hoy
setlocale(LC_TIME, 'es_ES');
$hoy = getdate();
$day=$hoy['mday'];
$month=$hoy['mon'];
$year=$hoy['year'];
// Conectando, seleccionando la base de datos
include_once "con.php";
$sentencia = $con->prepare("SELECT * FROM congratulations WHERE id= ?;");
$sentencia->execute([1]);
$result = $sentencia->fetchAll(PDO::FETCH_OBJ);
$estado ="active";
$congratulations = "";
$contador=0;
foreach($result as $fila) {
    $congratulations .= '<div class="carousel-item '.$estado.'">';
    $estado="";
    $col_image=($fila->image==NULL) ? "default.png" : "felicitaciones/homenajeado".$fila->id."/".$fila->image ;
    $col_title=$fila->title;
    $col_detail=$fila->detail;
    $congratulations .= '<div class="not-item">';
    $congratulations .= '<div class="item-t ">'.$col_title.'</div>';
    $congratulations .= '<div class="row">';
    $congratulations .= '<div class="card sin-border">';
    $congratulations .= '<div class="card-body">';
    $congratulations .= '<div class="col" style="border-color: transparent;"><img class="img-l" src="../images/'.$col_image.'" /></div>';
    $congratulations .= '</div></div>';
    $congratulations .= '<div class="col" style="border-color: transparent;">';
    $congratulations .= '<div class="card sin-border">';
    $congratulations .= '<div class="card-body">';
    $congratulations .= '<p class="card-text text-left"> Ciudad: '.$col_detail.'</p>';
    $congratulations .= '</div></div></div></div></div></div>';
    $contador++;
}
$congratulations .= ($contador>0) ? "" : "<div class='carousel-item active'><div class='cum-item'><div class='name fleft'>No hay cumpleaños el dia de hoy</div></div></div>";





$sentencia = $con->prepare("SELECT * FROM birthdays WHERE day= ? AND month= ?;");
$sentencia->execute([$day, $month]);
$result = $sentencia->fetchAll(PDO::FETCH_OBJ);
$estado ="active";
$birthdays = "";
$contador=0;
foreach($result as $fila) {
    $birthdays .= '<div class="carousel-item '.$estado.'">';
    $estado="";
    $birthdays .= '<div class="cum-item">';
    $col_image=($fila->image==NULL) ? "default.png" : $fila->id."/".$fila->image ;
    $col_name=$fila->name;
    $col_surname=$fila->surname;
    $col_job=$fila->job;
    $birthdays .= '<div class="img-cum fleft sin-border"><img class="img-l" src="../images/'.$col_image.'" /></div>';
    $birthdays .= '<div class="col sin-border">';
    $birthdays .= '<div class="row">';
    $birthdays .= '<div class="name fleft">'.$col_name.'<br/>'.$col_surname.'</div></div>';
    $birthdays .= '<div class="row">';
    $birthdays .= '<div class="cargo fel "> '.$col_job.'</div>';
    $birthdays .= '</div></div></div></div>';
    $contador++;
}
$birthdays .= ($contador>0) ? "" : "<div class='carousel-item active'><div class='cum-item'><div class='name fleft'>No hay cumpleaños el dia de hoy</div></div></div>";
$sentencia = $con->prepare("SELECT * FROM events WHERE year>= ?");
$sentencia->execute([2018]);
$result = $sentencia->fetchAll(PDO::FETCH_OBJ);
$estado ="active";
$events = "";
foreach($result as $fila) {
    $events .= '<div class="carousel-item '.$estado.'">';
    $estado="";
    $events .= '<div class="event-item">';
    $events .= '<div class="row">';
    $col_name = $fila->name;
    $col_description = $fila->description;
    $col_city = $fila->city;
    $col_place = $fila->place;
    $col_day = $fila->day;
    $col_month = strftime("%B", DateTime::createFromFormat('m', $fila->month)->getTimestamp()); 
    $col_month = ucwords(strtolower($col_month));
    $col_hour = strftime("%I", DateTime::createFromFormat('H', $fila->hour)->getTimestamp());
    $col_minute = $fila->minute;
    $col_format = DateTime::createFromFormat("H", $col_hour);
    $col_format = $col_format->format("a");
    $events .= '<div class="card sin-border">';
    $events .= '<div class="card-body">';
    $events .= '<div class="col sin-border"><h3 class="text-truncate text-center">'.$col_day.'<small> '.$col_month.'</small></h3></div>';
    $events .= '</div></div>';
    $events .= '<div class="col sin-border">';
    $events .= '<div class="card sin-border" style="border-left-color: rgba(0, 0, 0, .10) !important;">';
    $events .= '<div class="card-body">';
    $events .= '<h2 class="card-title text-left">'.$col_name.'</h2>';
    $events .= '<p class="card-text text-left"> Ciudad: '.$col_city.'</p>';
    $events .= '<p class="card-text text-left">Lugar: '.$col_place.'</p>';
    $events .= '<p class="card-text text-left">Hora: '.$col_hour.':'.$col_minute.' '.$col_format.'</p>';
    $events .= '<p class="card-text text-left"><small>Interesados escribir a info@iqinterquirofanos.co</small></p>';
    $events .= '</div></div></div></div></div></div>';
    $contador++;
}

si al controlador le agrego :

echo $congratulations.$birthdays.$events;


?>

en el console me sale esto:

introducir la descripción de la imagen aquí

como pueden ver me muestra el código html de las consultas que necesito.

pero si poor el contrario agrego al controlador esto:

header('Content-Type: application/json');

//Guardamos los datos en un array
$datos = array(
'estado' => 'ok',
'congratulations' => $congratulations,
'birthdays' => $birthdays,
'events' => $events
);
//Devolvemos el array pasado a JSON como objeto
echo json_encode($datos, JSON_FORCE_OBJECT);

?>

me sale esto: introducir la descripción de la imagen aquí

Andrés Vélez
  • 579
  • 1
  • 7
  • 25
  • Es muy probable que los datos estén viniendo mal codificados, lo cual provocaría un JSON erróneo. Los problemas de codificación son de varios niveles, por lo pronto, vamos a probar con la conexión, pues suele ser el más frecuente. Puedes indicar a la conexión que use `UTF-8` para los datos que vengan de la BD. Justo después de esta línea: `include_once "con.php";` pon esto: **`$con->query("SET NAMES 'utf8'");`** pon también el charset en **`header("Content-type: application/json; charset=utf-8");`** y dime si ahora funciona el JSON. No olvides poner de nuevo el dataType en la llamada Ajax. – A. Cedano Nov 14 '18 at 01:55
  • @A.Cedano, gracias al parecer era eso, ya en un par de días te cuento; algo que me parece raro es que el viernes antes de irme funcionaba, sabes a que se debe que dejara de funcionar de un momento a otro? – Andrés Vélez Nov 14 '18 at 13:29
  • Andrés, a mi en el pasado me ocurrió que, de un momento a otro, un código que funcionaba bien en un escenario, de un momento a otro dejaba de funcionar. En mi caso era porque había cambiado la configuración de PHP en un sitio web alojado en un hosting compartido (la nueva configuración alteraba algo en la codificación y salían caracteres extraños en los datos provenientes de mi base de datos). Yo llegué a la conclusión de que había que tener en todo momento un control estricto de la codificación en todos los niveles donde se mueven nuestros datos... – A. Cedano Nov 14 '18 at 14:20
  • ...basándome en esa experiencia, [respondí a una pregunta aquí en Stackoverflow](https://es.stackoverflow.com/a/59510/29967) explicando con detalle en qué consiste ese control de codificación *por niveles*. Desde que lo he hecho así no he tenido jamás ningún problema de caracteres raros. Además, eso evita tener que estar aplicando funciones de codificación sobre cada dato o cada variable que querramos presentar. Digamos que, se trata de trabajar en un entorno correctamente configurado en cada nivel y despreocuparse del resto. – A. Cedano Nov 14 '18 at 14:22

2 Answers2

0

Tu archivo .php parece no estar codificado correctamente que en el html que generas hay caracteres �.

Verifica que tu archivo esté codificado en UTF-8 sin BOM.

Y asegurate de guardarlo con dicha codificación usando tu editor de texto/IDE preferido.

introducir la descripción de la imagen aquí

Erick Patrick
  • 326
  • 1
  • 5
  • No, no es eso, ya que los datos que eso trae no están quemados en el php, son extraídos de una base de datos. O eso creería yo. – Andrés Vélez Nov 14 '18 at 13:30
0

Hay que aplicar una codificación adecuada por niveles, yendo a la raíz del problema.

En tu caso, tendrías que actuar sobre dos cuestiones claves:

  • El header de tu JSON
  • La conexión a la base de datos

Conviene siempre indicar la codificación cuando creas un JSON:

header("Content-type: application/json; charset=utf-8");

Y también indicar al objeto de conexión, que traiga los datos de la base de datos codificados de acuerdo a lo que necesitas:

$con->query("SET NAMES 'utf8'"); 

Con respecto a la conexión, para no tener que estar haciendo cada vez esta consulta, puedes indicar que quieres codificación utf-8 cuando creas la conexión misma.

Hay dos formas de hacerlo:

  1. Pasándolo en un array de opciones. Esta es mi forma preferida, porque de paso, por seguridad, conviene que apagues las preparaciones emuladas cuando usas PDO y que configures bien el manejo de errores. Así que puedes crear un array con todas las opciones y pasarlo al constructor de tu objeto PDO:

      /*
           *Array de opciones para configurar la conexión
           *Es MUY IMPORTANTE setear estas tres opciones cuando usas PDO
      */
      $options = array(
              PDO::ATTR_EMULATE_PREPARES => FALSE, 
              PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, 
              PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES 'utf8'"
    
       /*Luego, pasas $options como último parámetro al constructor*/
       $pdo = new PDO($dsn, $usr, $pwd, $options);
    

    ATTR_EMULATE_PREPARES evita las preparaciones emuladas, que podrían ser un riesgo de seguridad de cara a la Inyección SQL.

    ERRMODE_EXCEPTION configura de forma correcta el manejo de errores. Por ejemplo, en algunos escenarios, cuando hay errores creando la conexión, PDO puede escribir en el log de errores tus credenciales de conexión, ¡incluida la contraseña!

    MYSQL_ATTR_INIT_COMMAND configura la conexión para que use utf-8, así, ya no tienes que mandar esta consulta cada vez que uses tu conexión: $con->query("SET NAMES 'utf8'");

  2. La codificación se puede pasar también directamente en el DSN, del siguiente modo:

    $con = new PDO("mysql:host=localhost;dbname=DB;charset=UTF8");
    

    Se pasa charset=UTF8 precedido de ; después del nombre de la base de datos. Si lo pones en el array de de opciones explicado en (1), ya no tendrías que hacerlo como se explica aquí en (2).

Pregunta relacionada

¿Por que el Carácter inspector (�) aparece en algunos datos obtenidos de la Base de Datos?

A. Cedano
  • 86,578
  • 19
  • 122
  • 221
  • Me funciono pero para ponerla en con.php estoy teniendo problemas, pues al hacerlo me falla, se queda igual que como sin meterle nada, es decir pasa lo mismo que en las imágenes que subí en la pregunta. – Andrés Vélez Nov 14 '18 at 16:48
  • getMessage(); } ?> – Andrés Vélez Nov 14 '18 at 16:49
  • @AndrésVélez yo veo que en tu código PHP tienes muchos elementos de texto como `div` y otras etiquetas HTML. Si lo que vas a devolver es contenido HTML entonces tienes que quitarle el `dataType: json` en la petición Ajax y el `header` en la parte de PHP. O cambiar todo el código, armando en el servidor un JSON correcto, el cual luego desglosarás en la parte de Ajax. En ese sentido tiene que haber coherencia entre lo que se espera en Ajax y lo que mandas desde el servidor. – A. Cedano Nov 14 '18 at 18:12