2012-03-01 20 views
6

Estoy tratando de enviar datos JSON desde un formulario utilizando el objeto XMLHttpRequest. Puedo enviar los datos usando la siguiente función. No se muestran errores en FireBug y los datos JSON en la solicitud se muestran bien formados por FireBug.Enviar datos JSON a PHP utilizando XMLHttpRequest sin jQuery

Sin embargo, enviar los datos a echo.php, lo que simplemente devuelve el contenido:

<?php 
print_r($_POST); 
print_r($_GET); 
foreach (getallheaders() as $name => $value) { 
    echo "$name: $value\n"; 
} 
echo file_get_contents('php://input'); 
?> 

El POST-array siempre está vacío, pero puedo ver la cadena JSON devuelto por file_get_contents. ¿Cómo sucede eso? ¿Qué estoy haciendo mal?

salida del echo.php

Array 
(
) 
Array 
(
) 
Host: localhost 
User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux i686; rv:10.0.2) Gecko/20100101 Firefox/10.0.2 
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 
Accept-Language: eo,de-de;q=0.8,de;q=0.6,en-us;q=0.4,en;q=0.2 
Accept-Encoding: gzip, deflate 
Connection: keep-alive 
Content-Type: application/json; charset=utf-8 
Referer: http://localhost/form.html 
Content-Length: 88 
Cookie: {{..to much data..}} 
Pragma: no-cache 
Cache-Control: no-cache 
{"type":"my_type","comment":"commented"} 

la función de envío:

function submit(){ 
    var data={}; 
    data.type=document.form.type.value; 
    data.comment=document.form.comment.value; 

    //get right XMLHttpRequest object for current browsrer 
    var x=ajaxFunction(); 

    var string = JSON.stringify(data); 

    x.open('POST','echo.php',true); 
    x.setRequestHeader('Content-type','application/json; charset=utf-8'); 
    x.setRequestHeader("Content-length", string.length); 
    x.setRequestHeader("Connection", "close"); 

    x.onreadystatechange = function(){ 
     if (x.readyState != 4) return; 
     if (x.status != 200 && x.status != 304) { 
      alert('HTTP error ' + req.status); 
      return; 
     } 

     data.resp = JSON.parse(x.responseText); 
     if(data.resp.status=='success'){ 
      alert('That worked!'); 
     }else{ 
      alert('That didn\'t work!'); 
     } 
    } 
    x.send(string); 

    return false; //prevent native form submit 
} 
+0

'alerta ('HTTP error' + req.status);' ==> req no definido, ¿quiso decir 'x' en su lugar? –

Respuesta

7

que se olvidó de asignar nombres a las variables de la función de envío. La buena manera de utilizarlo es

x.send('name1='+string+'&name2=value2'); 

Teniendo en cuenta que, creo que tendrá que cambiar la cabecera Content-Length. No creo que sea útil enviarlo.

Otra cosa que puedes hacer es probar con el método GET. También puede tratar de cambiar la cabecera de tipo de contenido por el que uno:

xmlhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded") 
+0

ya lo intenté pero no cambia el comportamiento. Recibo 'data = {" type ":" my_type "," comment ":" comentó "}' en PHP, pero '$ _POST' está vacío. ¿Tengo que escapar de la 'cadena'? ¿Cómo? – Simon

+1

Una cosa que puede hacer es reemplazar su encabezado de tipo de contenido con ese: x.setRequestHeader ("Content-type", "application/x-www-form-urlencoded") – artragis

+0

¡Gracias! ¡Eso funciono! Me parece muy desagradable. Pero si es la única forma, lo haré así. – Simon

5

PHP no procesa las peticiones JSON de forma automática como lo hace con las solicitudes de forma codificados o varias partes. Si desea usar JSON para enviar solicitudes a PHP, básicamente lo está haciendo correctamente con file_get_contents(). Si desea fusionar esas variables en su objeto $ _POST global, puede hacerlo, aunque no recomendaría hacerlo, ya que podría ser confuso para otros desarrolladores.

// it's safe to overwrite the $_POST if the content-type is application/json 
// because the $_POST var will be empty 
$headers = getallheaders(); 
if ($headers["Content-Type"] == "application/json") 
    $_POST = json_decode(file_get_contents("php://input"), true) ?: []; 

Nota rápida: no debe enviar un juego de caracteres con su tipo de contenido para la aplicación/json. Esto solo debe enviarse con text/* Content-Types.

Cuestiones relacionadas