web-dev-qa-db-ja.com

PHPへのAngularJS HTTPポストおよび未定義

ng-submit="login()タグを持つフォームがあります

関数は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');
        });
    }
}

PHPファイルから200 OK応答を返していますが、返されたデータはemailpasswordが未定義であると言っています。これは私が持っているすべてのPHPです

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

未定義のPOST値を取得している理由は何ですか?

編集

これは一般的な質問であるようですが(古い)、.success.errorは非推奨になりました。コメントで@James Gentesが指摘したように.thenを使用する必要があります。

105
Ronnie

angularjs .post()は、Content-typeヘッダーをデフォルトでapplication/jsonに設定します。フォームエンコードされたデータを渡すためにこれをオーバーライドしていますが、適切なクエリ文字列を渡すためにdata値を変更していないので、PHPは期待どおり$_POSTを設定していません。

私の提案は、application/jsonのデフォルトのangularjs設定をヘッダーとして使用し、PHPで生の入力を読み取り、JSONをデシリアライズすることです。

これは、次のようにPHPで実現できます。

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

または、$_POST機能に大きく依存している場合は、[email protected]&password=somepasswordのようなクエリ文字列を作成し、それをデータとして送信できます。このクエリ文字列がURLエンコードされていることを確認してください。 (jQuery.serialize()のようなものを使用するのではなく)手動でビルドした場合、JavascriptのencodeURIComponent()があなたのためのトリックを行うはずです。

222
Mike Brant

私は私のinitファイルの最初で、サーバー側でそれを行い、魅力のように機能し、angularまたは既存のPHPコードで何もする必要はありません:

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

私が開発しているAPIにはベースコントローラーがあり、その__construct()メソッド内には次のものがあります。

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));
}

これにより、必要なときにjsonデータを$ _POST ["var"]として単純に参照できます。よく働く。

認証されたユーザーがデフォルトのContent-Type:application/x-www-form-urlencodedまたはContent-Type:application/jsonで投稿データを送信するjQueryなどのライブラリに接続すると、APIはエラーなしで応答します。 APIをもう少し開発者に優しいものにします。

お役に立てれば。

14
Tim Wickstrom

PHPはJSONをネイティブに受け入れないため'application/json' 1つの方法は、angularからヘッダーとパラメーターを更新して、APIがデータを直接使用できるようにすることです。

最初、データのパラメーター化:

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

Then、以下を$httpに追加します

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

すべてのリクエストがPHPに送信される場合、パラメータは次のように設定でグローバルに設定できます:

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);
        });

        }]);

サーバーサイドコード:-

<?php


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

?>

angularの動作により、PHPサーバーで通常の投稿動作を行う直接的な方法はないため、jsonオブジェクトで管理する必要があります。

8

.post()に2番目のパラメーターとして渡す前に、フォームデータを逆シリアル化する必要があります。これは、jQueryの$ .param(データ)メソッドを使用して実現できます。その後、サーバー側で$ .POST ['email']のように参照できるようになります。

6
bahramzy

これはjQueryとJSONデコードを必要としないため、最良のソリューション(IMO)です。

ソース: https://wordpress.stackexchange.com/a/17937 and: https://stackoverflow.com/a/1714899/196507

概要:

//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';
});

例:

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

PHPコード:

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

古い質問ですが、Angular 1.4に$ httpParamSerializerが追加され、$ http.postを使用する場合、$ httpParamSerializer(params)を使用してパラメーターを渡すと、すべてが通常の投稿のように機能することに言及する価値がありますサーバー側でJSONの逆シリアル化が要求されることはありません。

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

5
Sep

AngularとPHPで作業していることを理解するのに何時間もかかりました。投稿データは$ _POSTのPHPに送信されませんでした

PHPコードで以下を実行します。 -変数$ angular_post_paramsを作成します-その後、次の$angular_http_params = (array)json_decode(trim(file_get_contents('php://input')));を実行します

これで、$ _ POSTから行うようにパラメーターにアクセスできます

$angular_http_params["key"]

あなたがjavascriptについて疑問に思っている場合....これは私が使用したものです

    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");
        });
    });
0
Talha