Chiamata Ajax con contentType: ‘application / json’ non funziona

Ho una chiamata Ajax, che invia i dati del modulo a una funzione PHP. Dal momento che ho letto molto sul fatto che l’uso di contentType: 'application/json' è la migliore pratica, ho voluto provare anche io. Ma sfortunatamente il mio script non restituisce nulla quando lo uso. Se lo rimuovo, lo script fa quello che dovrebbe fare.

Hai idea di quale potrebbe essere la ragione e perché? Grazie!

 $('#Form').submit(function(e) { e.preventDefault(); var content = $(this).serialize() + "&ajax=1"; $.ajax('app/class/controller/contactForm.php', { type: "POST", //contentType: 'application/json', dataType: 'json', data: content, success: function(result) { console.log(result); } }); }) 

e il mio PHP:

 if(isset($_POST['ajax']) && $_POST['ajax'] === '1') { echo json_encode(validateForm($_POST)); } 

Quando usi contentType: 'application/json' potrai contare su $_POST popolato. $_POST viene popolato solo per i tipi di contenuto con codifica modulo.

Come tale, è necessario leggere i dati dall’input raw di PHP come questo:

 $input = file_get_contents('php://input'); $object = json_decode($input); 

Naturalmente se vuoi inviare l’ application/json dovresti effettivamente inviare JSON, cosa che non stai facendo. È necessario creare direttamente la serializzazione degli oggetti su JSON, oppure è necessario fare qualcosa di simile – Converti i dati del modulo in object JavaScript con jQuery – per serializzare l’object dal modulo.

Onestamente nel tuo caso, dal momento che hai a che fare con i dati dei moduli, non penso che il caso d’uso per l’uso di application/json sia lì.

La procedura consigliata a cui si fa riferimento riguarda lo script del server che imposta Content-Type per JSON su “application / json”:

 Header('Content-Type: application/json; charset=UTF8'); 

Questo perché altrimenti verrà inviato un Content-Type default, spesso un text/html tipo catch-all, e questo potrebbe portare a un’incomprensione con il cliente.

Se non si specifica un tipo di contenuto nella richiesta jQuery, jQuery determinerà il più appropriato. Il problema qui è che si inviava un modulo POST , per il quale il tipo di Content-Type predefinito impostato da jQuery è application/x-www-form-urlencoded , che indica a PHP di decodificare i dati come campi POST e popolare $_POST . Lo script avrebbe quindi recuperato i suoi parametri da $_POST (o forse $_REQUEST ).

Cambiando l’ application/json , $_POST non verrà più popolato, l’operazione di script ricevente non riceverà i parametri in cui si aspettava e l’operazione si interrompe.

Quindi è necessario:

  • non specificare tu stesso il tipo di contenuto (meglio, IMHO)
  • impostare un Content-Type of application/x-www-form-urlencoded; charset=UTF-8 application/x-www-form-urlencoded; charset=UTF-8
  • impostare un Content-Type of application/json; charset=UTF-8 application/json; charset=UTF-8 e modifica lo script per analizzare il stream POST e decodificare i dati JSON; vedi questa risposta

La terza opzione richiede una corretta gestione di php://input .

Lo script PHP dovrebbe impostare l’intestazione Content-Type.

 if(isset($_POST['ajax']) && $_POST['ajax'] === '1') { header('Content-Type: application/json'); echo json_encode(validateForm($_POST)); }