web-dev-qa-db-fra.com

Message HTTP AngularJS sur PHP et indéfini

J'ai un formulaire avec la balise ng-submit="login()

La fonction s'appelle bien en javascript.

function LoginForm($scope, $http)
{
    $http.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded; charset=UTF-8';

    $scope.email    = "[email protected]";
    $scope.password = "1234";

    $scope.login = function()
    {
        data = {
            'email' : $scope.email,
            'password' : $scope.password
        };

        $http.post('resources/curl.php', data)
        .success(function(data, status, headers, config)
        {
            console.log(status + ' - ' + data);
        })
        .error(function(data, status, headers, config)
        {
            console.log('error');
        });
    }
}

Je reçois une réponse 200 OK du fichier PHP. Toutefois, les données renvoyées indiquent que email et password sont indéfinis. C'est tout le php que j'ai

<?php
$email = $_POST['email'];
$pass  = $_POST['password'];
echo $email;
?>

Une idée de la raison pour laquelle je reçois des valeurs non définies POST?

EDIT

Je tenais à préciser que cela semble être une question courante (et pourtant ancienne), .success et .error ont été déconseillés et vous devez utiliser .then comme l'a souligné @James Gentes dans les commentaires

106
Ronnie

angularjs .post() définit par défaut l'en-tête Content-type sur application/json. Vous redéfinissez cette option pour transmettre des données codées au format. Toutefois, vous ne modifiez pas votre valeur data pour transmettre une chaîne de requête appropriée. Par conséquent, PHP ne remplit pas $_POST comme prévu.

Ma suggestion serait d'utiliser simplement le paramètre angularjs par défaut de application/json comme en-tête, de lire l'entrée brute en PHP, puis de désérialiser le fichier JSON.

Cela peut être réalisé dans PHP comme ceci:

$postdata = file_get_contents("php://input");
$request = json_decode($postdata);
$email = $request->email;
$pass = $request->password;

Si vous vous fiez beaucoup à la fonctionnalité $_POST, vous pouvez également former une chaîne de requête du type [email protected]&password=somepassword et l'envoyer sous forme de données. Assurez-vous que cette chaîne de requête est une URL encodée. S'il est construit manuellement (par opposition à l'utilisation de quelque chose comme jQuery.serialize()), le encodeURIComponent() de Javascript devrait faire l'affaire pour vous.

223
Mike Brant

Je le fais côté serveur, au début de mon fichier init, fonctionne comme un charme et vous n'avez rien à faire dans angular ou dans le code php existant:

if ($_SERVER['REQUEST_METHOD'] == 'POST' && empty($_POST))
    $_POST = json_decode(file_get_contents('php://input'), true);
39
valmarv

Dans l'API que je développe, j'ai un contrôleur de base et dans sa méthode __construct (), j'ai les éléments suivants:

if(isset($_SERVER["CONTENT_TYPE"]) && strpos($_SERVER["CONTENT_TYPE"], "application/json") !== false) {
    $_POST = array_merge($_POST, (array) json_decode(trim(file_get_contents('php://input')), true));
}

Cela me permet simplement de référencer les données JSON sous forme de $ _POST ["var"] lorsque cela est nécessaire. Fonctionne très bien.

Ainsi, si un utilisateur authentifié se connecte à une bibliothèque telle que jQuery qui envoie des données de publication avec le type de contenu par défaut Content-Type: application/x-www-form-urlencoded ou Content-Type: application/json, l’API répondra sans erreur et rendre l'API un peu plus conviviale pour les développeurs.

J'espère que cela t'aides.

14
Tim Wickstrom

Parce que PHP n'accepte pas nativement JSON 'application/json' Une solution consiste à mettre à jour vos en-têtes et paramètres à partir de angular afin que votre API puisse utiliser les données directement.

First, Paramétrez vos données:

data: $.param({ "foo": $scope.fooValue })

Alors, ajoutez ce qui suit à votre $http

 headers: {
     'Content-Type' : 'application/x-www-form-urlencoded; charset=UTF-8'
 }, 

Si toutes vos demandes sont dirigées vers PHP, les paramètres peuvent être définis globalement dans la configuration, comme suit:

myApp.config(function($httpProvider) {
    $httpProvider.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded; charset=UTF-8';
});
11
Malkus

Angular Js Demo Code: -

angular.module('ModuleName',[]).controller('main', ['$http', function($http){

                var formData = { password: 'test pwd', email : 'test email' };
                var postData = 'myData='+JSON.stringify(formData);
                $http({
                        method : 'POST',
                        url : 'resources/curl.php',
                        data: postData,
                        headers : {'Content-Type': 'application/x-www-form-urlencoded'}  

                }).success(function(res){
                        console.log(res);
                }).error(function(error){
                        console.log(error);
        });

        }]);

Code côté serveur: -

<?php


// it will print whole json string, which you access after json_decocde in php
$myData = json_decode($_POST['myData']);
print_r($myData);

?>

En raison du comportement angular, il n'existe pas de méthode directe pour le comportement normal des publications sur le serveur PHP. Vous devez donc le gérer dans des objets JSON.

8
Rajendra Khabiya

Vous devez désérialiser vos données de formulaire avant de les transmettre en tant que deuxième paramètre à .post (). Vous pouvez y parvenir en utilisant la méthode $ .param (data) de jQuery. Ensuite, vous pourrez, côté serveur, le référencer comme $ .POST ['email'];

6
bahramzy

C'est la meilleure solution (IMO) car elle ne nécessite ni jQuery ni décodage JSON:

Source: https://wordpress.stackexchange.com/a/17937 et: https://stackoverflow.com/a/1714899/196507

Sommaire:

//Replacement of jQuery.param
var serialize = function(obj, prefix) {
  var str = [];
  for(var p in obj) {
    if (obj.hasOwnProperty(p)) {
      var k = prefix ? prefix + "[" + p + "]" : p, v = obj[p];
      str.Push(typeof v == "object" ?
        serialize(v, k) :
        encodeURIComponent(k) + "=" + encodeURIComponent(v));
    }
  }
  return str.join("&");
};

//Your AngularJS application:
var app = angular.module('foo', []);

app.config(function ($httpProvider) {
    // send all requests payload as query string
    $httpProvider.defaults.transformRequest = function(data){
        if (data === undefined) {
            return data;
        }
        return serialize(data);
    };

    // set all post requests content type
    $httpProvider.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded; charset=UTF-8';
});

Exemple:

...
   var data = { id: 'some_id', name : 'some_name' };
   $http.post(my_php_url,data).success(function(data){
        // It works!
   }).error(function() {
        // :(
   });

Code PHP:

<?php
    $id = $_POST["id"];
?>
6
lepe

C'est une vieille question mais il convient de mentionner que dans Angular 1.4 $ $ httpParamSerializer est ajouté et lorsque vous utilisez $ http.post, si vous utilisez $ httpParamSerializer (params) pour passer les paramètres, tout fonctionne comme un message régulier demande et aucune désérialisation JSON n'est nécessaire côté serveur.

https://docs.angularjs.org/api/ng/service/$httpParamSerializer

5
Sep

Cela m'a pris des heures pour comprendre cela en travaillant avec Angular et PHP. Les données de publication n'allaient pas sur PHP dans $ _POST

dans PHP code, procédez comme suit. - Créez une variable $ angular_post_params - Puis procédez comme suit $angular_http_params = (array)json_decode(trim(file_get_contents('php://input')));

vous pouvez maintenant accéder à vos paramètres comme vous le faites à partir de $ _POST

$angular_http_params["key"]

au cas où vous vous interrogeriez sur javascript .... c'est ce que j'ai utilisé

    var myApp = angular.module('appUsers', []);
    //var post_params = $.param({ request_type: "getListOfUsersWithRolesInfo" });
    var dataObj = {
        task_to_perform: 'getListOfUsersWithRolesInfo'
    };

    myApp.controller('ctrlListOfUsers', function ($scope, $http) {
        $http({
            method: 'POST',
            dataType: 'json',
            url: ajax_processor_url,
            headers: {
                'Content-Type': 'application/json'
            },
            data: dataObj,
            //transformRequest: function(){},
            timeout: 30000,
            cache: false
        }).
        success(function (rsp) {
            console.log("success");
            console.log(rsp);
        }).
        error(function (rsp) {
            console.log("error");
        });
    });
1
Talha