AngularJS : $http.post() n'envoie pas les données, comment faire ?

L'erreur provient d'une confusion entre deux méthodes post() : celle utilisée par la bibliothèque JQuery et celle d'AngularJS.

Lorsque l'on utilise le framework AngularJS dans une application déjà développée en PHP, on constate que l'on n'arrive pas à récupérer les données qui sont envoyées par la méthode $http.post().

Cette erreur provient d'une confusion entre deux méthodes post() : celle utilisée par la bibliothèque JQuery et celle d'AngularJS. Ces deux méthodes ont le même but, mais ne se comportent pas de la même façon pour la sérialisation et la transmission des données.

Avec la méthode JQuery.post(), les données sont transférées avec le type de contenu x-www-form-urlencoded, ce qui signifie qu'elles sont encodées dans l'URL. Leur forme est la suivante :

parametre1=valeur1¶metre2=valeur2

Avec la méthode $http.post() d'AngularJS, les données sont de type application/json. Les données sont donc sérialisées en JSON. Leur forme est différente :

{ parametre1: valeur1, parametre2: valeur2 }

Certains langages, dont PHP, ne désérialisent pas nativement le JSON. Les données ne sont donc pas transférées correctement.

Pour corriger ce problème, il faut écrire dans le module de votre application une fonction qui redéfinit le comportement de la méthode $http.post().
angular.module('MyModule', [], function($httpProvider) {
// On utilise le type de contenu x-www-form-urlencoded
$httpProvider.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded;charset=utf-8';
/**
* Fonction qui convertit un objet JSON en chaîne de caractères sérialisé avec le type x-www-form-urlencoded.
*/
var param = function(obj) {
var query = '', name, value, fullSubName, subName, subValue, innerObj, i;
for(name in obj) {
value = obj[name];
if(value instanceof Array) {
for(i=0; i<value.length; ++i) {
subValue = value[i];
fullSubName = name + '[' + i + ']';
innerObj = {};
innerObj[fullSubName] = subValue;
query += param(innerObj) + '&';
}
}
else if(value instanceof Object) {
for(subName in value) {
subValue = value[subName];
fullSubName = name + '[' + subName + ']';
innerObj = {};
innerObj[fullSubName] = subValue;
query += param(innerObj) + '&';
}
}
else if(value !== undefined && value !== null)
query += encodeURIComponent(name) + '=' + encodeURIComponent(value) + '&';
}
return query.length ? query.substr(0, query.length - 1) : query;
};
// On remplace le type de contenu par défaut utilisé par la fonction $http.post()
$httpProvider.defaults.transformRequest = [function(data) {
return angular.isObject(data) && String(data) !== '[object File]' ? param(data) : data;
}];
});

AngularJS