votos votaciones votacion sistema likes estrellas conteo con calificar php javascript jquery ajax http

php - votaciones - Actualizar toda la página en la solicitud de Ajax



sistema de votaciones (6)

Tengo una solicitud AJAX que puede tener dos resultados posibles:

  1. El servidor responde con un mensaje que debo colocar en un <div>
  2. El servidor responde con una página HTML, en este caso necesito sustituir la página actual por una nueva y cambiar la dirección (el cliente conoce la dirección antes de una solicitud).

¿Cuál sería la solución si tengo la solicitud de AJAX que necesita manejar ambos casos?

url = "http://example.com" ajax.request(callback) function callback(response) { if (case2(response)) { history.pushState({}, "New page", url); document.innerHTML = response } else { updateDiv(response) } }

Me interesa una forma correcta de implementar la primera rama, o si el servidor puede componer un encabezado que haga que el navegador maneje una respuesta como una respuesta HTTP habitual y actualice la ubicación y el contenido de una página, algo así como redireccionar con contenido dado .

Entiendo que el servidor puede devolver un enlace en lugar de una página, pero en este caso se necesitará una etapa adicional en un cliente: redirigir y luego rellenar la nueva página en el servidor.


Dado que la solicitud es para una respuesta actualizada, aquí está mi solución utilizando la API de historial de HTML5 con jQuery . Debería ejecutarse fácilmente combinando las partes de PHP y HTML en un archivo.

Mi solución permite que AJAX devuelva lo siguiente:

  1. Un mensaje a través de AJAX, que actualiza un contenedor <div> .
  2. Una URL, que hace que el navegador redirija a la URL
  3. Una página HTML completa, que llama history.pushState() del API del history.pushState() para agregar la URL actual al historial del navegador y reemplaza todo el HTML de la página con el HTML devuelto por AJAX.

PHP

Esto es solo una muestra de lo que el script PHP deberá devolver cuando se invoca a través de AJAX. Muestra cómo codificar indicadores para determinar si la llamada AJAX debe actualizar el contenedor o cargar una nueva página, y cómo devolver su resultado a través de JSON a través de json_encode . Para completar, nombré este script test.php .

<?php // Random messages to return $messages = array( '''', ''Error Message'', ''Testing'' ); // If the page was requested via AJAX if( isset( $_POST[''ajax''])) { $response = array( ''redirect'' => // Flag to redirect ( rand() % 2 == 0) ? true : false, ''load_html'' => // Flag to load HTML or do URL redirect ( rand() % 2 == 0) ? true : false, ''html'' => // Returned HTML ''<html><head><title>AJAX Loaded Title</title></head><body>It works!</body></html>'', ''title'' => ''History API previous title'', ''message'' => // Random message $messages[ (rand() % count( $messages)) ] ); echo json_encode( $response); exit; }

JS

Ya que estoy usando jQuery, comencemos con eso. Lo siguiente envía un AJAX POST al servidor, al script PHP anterior en la URL test.php . Tenga en cuenta que también establece el parámetro POST ajax como true , lo que permite que el script PHP detecte que recibió una solicitud AJAX. El campo dataType le dice a jQuery que la respuesta del servidor estará en JSON y que debería descodificar ese JSON a un objeto JSON en la devolución de llamada de respuesta. Finalmente, la devolución de llamada success , que se activa cuando la respuesta AJAX se recibe con éxito, determina qué hacer en función de los indicadores enviados desde el servidor.

$.ajax({ type: ''POST'', url: "/test.php", data: {ajax : true}, dataType: "json", success: function( json) { if( json.redirect) { if( json.load_html) { // If the History API is available if( !(typeof history.pushState === ''undefined'')) { history.pushState( { url: redirect_url, title: document.title}, document.title, // Can also use json.title to set previous page title on server redirect_url ); } // Output the HTML document.open(); document.write( json.html); document.close(); } else { window.location = redirect_url; } } else { $(''#message'').html( json.message); } }, });

HTML

Aquí está la fuente HTML completa de mi archivo probado. Lo probé en FF4 - FF8. Tenga en cuenta que jQuery proporciona el método ready para evitar que JS se ejecute hasta que se cargue el DOM. También he utilizado el alojamiento de Google de jQuery, por lo que no necesita cargar una copia de jQuery a su servidor para probar esto.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <script src="//ajax.googleapis.com/ajax/libs/jquery/1.7.0/jquery.min.js" type="text/javascript"></script> <title>Default Page</title> <script type="text/javascript""> $( document).ready( function() { $(''#ajax_link'').click( function() { var redirect_url = "/test.php"; $.ajax({ type: ''POST'', url: "/test.php", data: {ajax : true}, dataType: "json", success: function( json) { if( json.redirect) { if( json.load_html) { // If the History API is available if( !(typeof history.pushState === ''undefined'')) { history.pushState( { url: redirect_url, title: document.title}, document.title, // Can also use json.title to set previous page title on server redirect_url ); } document.open(); document.write( json.html); document.close(); } else { window.location = redirect_url; } } else { $(''#message'').html( json.message); } }, }); }) }); </script> </head> <body> <div id="message">The default contents of the message</div> <a id="ajax_link" href="#">Fire AJAX</a> </body> </html>


Dale un id al cuerpo <body id="page"> y tu otro div será <div id="message"></div> ahora tu ajax se verá como

$.ajax({ url:''myAjax.php'', data:{datakey:datavalue}, dataType:"JSON", success: function (response) { if(response.message=="your message") { $(''#message'').html(response.content); } else { $(''#page'').html(response.content); } } });


Es realmente fácil si la respuesta es XML válido.

var new_doc = (new DOMParser).parseFromString(response, "application/xml"); document.replaceChild(document.adoptNode(new_doc.doctype), document.doctype); document.replaceChild(document.adoptNode(new_doc.documentElement), document.documentElement);


Francamente, creo que ese enfoque está básicamente roto por el diseño. No deberías tener que tomar esa decisión en ese lugar. Por ejemplo, la respuesta ajax solo podría indicar que se debe cargar una página completamente nueva y luego se debe generar el nuevo contenido en una segunda solicitud (no ajax) a una nueva URL.

En caso de que se vea obligado a tomar el camino que ya lleva, y siempre que el contenido de la respuesta no sea muy grande, puede probar los URI de Javascript. Básicamente, un URI en forma de javascript:"string" cargará una nueva página para la cual esa cadena es el código fuente. Por lo tanto, si la response ya es una cadena, solo debe asignar javascript:response a window.location.href . Tal vez tengas que hacer algún escape de antemano. Y no sé qué tan compatible con este navegador es este enfoque.

<a href="javascript:response">load</a>

También es posible.

Una variante de esto es construir la URL no con el nombre de la variable, sino con los datos de la cadena real. Me gusta

function source2url(src) { // make valid javascript string from source text var esc1 = src .replace(////g, ''////') .replace(//'/g, ''///''') .replace(//x0A/g, ''//x0A'') .replace(//x0D/g, ''//x0D''); // make valid url from that return "javascript:''" + encodeURIComponent(esc1) + "''"; } window.location.href = source2url(response);

Esto, por supuesto, generará URIs bastante grandes. Y siempre tendrás el Javascript-URI en la barra de direcciones.

ACTUALIZAR

Un enfoque similar es utilizar la codificación base64 en un URI de datos. La entrada de Wikipedia explica cómo funciona, incluido un ejemplo de javascript. Sin embargo, tendrías que base64-encode en base64-encode el contenido de alguna manera. (Nota: puede usar los URI de datos con o sin la codificación base64. Debe ver qué es lo que le brinda URI más cortos para su contenido específico).


Tuve un problema similar una vez. Se devolvió una página de error completa en lugar de un fragmento de código HTML simple. Eventualmente arreglamos esto cambiando la lógica, pero aquí está una de las soluciones que encontré:

document.open(); document.write(responseText); document.close();

La razón por la que abandonamos esto es que en IE hubo algunos problemas. No perdí tiempo para investigar por qué, pero lanzó una excepción de ''Acceso denegado'' al intentar escribir la cadena. Creo que hubo algunas etiquetas <meta> que confundieron IE, o tal vez comentarios condicionales, no estoy seguro. (Funcionó cuando usé algunas páginas simples ...)

La conclusión es: no debería tener que hacer esto, pero si no hay nada más que pueda hacer (como devolver una cadena de URL), el código anterior podría funcionar.


como dice T-Bull ... todo el proceso está mal aquí ...

simplemente estás exagerando las cosas y sabes que de hecho:

Entiendo que el servidor puede devolver un enlace en lugar de una página, pero en este caso se necesitará una etapa adicional en un cliente: redirigir y luego rellenar la nueva página en el servidor.

Deja de complicarte y empieza a hacerlo bien ...

  1. El cliente abre la página por primera vez, por lo tanto, $_SESSION[''tmp_client_id''] = ''client_''.session_id(); obviamente, es mejor si el cliente ya está suscrito, de todos modos, ponga cosas en la tabla temporal O en otra var de sesión, etc.
  2. Cliente rellene el formulario;
  3. Cliente enviar el formulario;
  4. Hacer la solicitud de AJAX;
  5. Almacene la variable $_POST dentro de tmp_client_tbl con su exclusivo tmp_client_id O solo $_SESSION[''client_''.session_id()] = json_encode($_POST);
  6. Resultado # 1? mostrar mensaje en un </div>
  7. Resultado # 2? actualice la página y compruebe if( isset($_SESSION[''client_''.session_id()])) { si es así, vamos a mostrar el formulario nuevamente con los campos rellenos: } else { mostrar formulario vacío;
  8. SELECT * FROM tmp_client_tbl WHERE tmp_client_id = ''{$_SESSION[''tmp_client_id'']}'' O json_decode($_SESSION[''client_''.session_id()]);
  9. $form_data = $mysql_rows; O $json_array;
  10. foreach($form_data as $name => $value) { echo "<input name=''$name'' value=''$value'' />" } de una forma ninja que asume que tiene ese tipo de matriz de formadores de formularios donde $form = array(''text'' => array(''name'',''lastname''), ''select'' => array(''countries''), ... ) , O simplemente por <input name=''lastname'' value=''{$lastname}'' /> donde los valores de los campos se prepululan con vars vacíos;
  11. tiempo transcurrido, error ocurrido, navegador cerrado? session_destroy(); o sin establecer unset($_SESSION[''client_''.session_id()]);