web-dev-qa-db-fra.com

Appel Ajax avec contentType: 'application/json' ne fonctionne pas

J'ai un appel ajax, qui envoie des données de formulaire à une fonction php. Depuis que j'ai lu beaucoup de choses sur l'utilisation de contentType: 'application/json' comme meilleure pratique, je voulais également essayer. Mais malheureusement, mon script ne renvoie rien lorsque je l'utilise. Si je le supprime, le script fait ce qu'il est censé faire. 

Avez-vous une idée de ce que la raison pourrait être et pourquoi? Je vous remercie!

$('#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);
              }
            });
        })

et mon PHP:

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

Lorsque vous utilisez contentType: 'application/json', vous ne pourrez pas compter sur $_POST qui sera rempli. $_POST n'est renseigné que pour les types de contenu codés par formulaire.

En tant que tel, vous devez lire vos données à partir de PHP raw input comme ceci:

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

Bien sûr, si vous souhaitez envoyer application/json, vous devez réellement envoyer du JSON, ce que vous ne faites pas. Vous devez soit créer la sérialisation d'objet au format JSON directement, soit procéder de la manière suivante:/ Convertissez les données de formulaire en objet JavaScript avec jQuery - pour sérialiser l'objet à partir du formulaire.

Honnêtement, dans votre cas, étant donné que vous traitez avec des données de formulaire, je ne pense pas que le cas d'utilisation de application/json existe.

18
Mike Brant

La meilleure pratique à laquelle vous faites référence concerne le le script de serveur, définissant le Content-Type pour JSON sur "application/json":

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

En effet, sinon, un Content-Type par défaut sera envoyé, souvent un text/html fourre-tout, ce qui pourrait entraîner une incompréhension avec le client.

Si vous not ne spécifiez pas vous-même un type de contenu dans la demande jQuery, jQuery déterminera celui qui convient le mieux. Le problème ici est que vous envoyiez un POST form, pour lequel le Content-Type par défaut défini par jQuery est application/x-www-form-urlencoded, qui indique à PHP de décoder les données. comme POST champs et peupler $_POST. Votre script aurait alors récupéré ses paramètres à partir de $_POST (ou peut-être $_REQUEST).

En le remplaçant par application/json, $_POST ne sera plus rempli, l'opération de script réceptrice ne recevra pas les paramètres attendus et l'opération sera interrompue.

Donc vous devez soit:

  • pas spécifier le type de contenu vous-même (mieux, à mon humble avis)
  • définir un type de contenu de application/x-www-form-urlencoded; charset=UTF-8
  • définir un type de contenu de application/json; charset=UTF-8 et modifier le script pour analyser le flux POST et décoder les données JSON; voir cette réponse .

La troisième option nécessite un traitement correct de php://input.

3
LSerni

Le script PHP doit définir l'en-tête Content-Type.

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