AngularJS HTTP post到PHP和未定义

AngularJS HTTP post到PHP和未定义,php,javascript,angularjs,Php,Javascript,Angularjs,我有一个标签为ng submit=“login() 该函数在javascript中可以很好地调用 function LoginForm($scope, $http) { $http.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded; charset=UTF-8'; $scope.email = "fsdg@sdf.com"; $scope.password = "1

我有一个标签为
ng submit=“login()

该函数在javascript中可以很好地调用

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

    $scope.email    = "fsdg@sdf.com";
    $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的回复,但是,返回的数据表明
电子邮件
密码
未定义。这就是我所有的PHP

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

知道我为什么会得到未定义的
POST
值吗

编辑

我想指出的是,由于这似乎是一个流行的问题(但它已经过时),
.success
.error
已被弃用,您应该使用
。然后,
正如@James Gentes在commments中指出的那样

angularjs
.post()
默认内容类型标题为
application/json
。您正在覆盖此标题以传递表单编码的数据,但是您没有更改
数据
值以传递适当的查询字符串,因此PHP不会像您预期的那样填充
$\u POST

我的建议是只使用默认的angularjs设置
application/json
作为标题,读取PHP中的原始输入,然后反序列化json

这可以在PHP中实现,如下所示:

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

或者,如果您严重依赖
$\u POST
功能,则可以形成类似
电子邮件的查询字符串=someemail@email.com&password=somepassword
并将其作为数据发送。确保此查询字符串是URL编码的。如果是手动生成的(而不是使用类似于
jQuery.serialize()
),Javascript的
encodeURIComponent()
应该可以帮到您。

在将表单数据作为第二个参数传递给.post()之前,您需要对表单数据进行反序列化。您可以使用jQuery的$.param(data)方法来实现这一点。
然后,您将能够在服务器端引用它,如$.POST['email'];

在我正在开发的API中,我有一个基本控制器,在它的u 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”],效果很好

这样,如果经过身份验证的用户连接到一个库,比如jQuery,该库发送post数据时默认的内容类型为:application/x-www-form-urlencoded或Content-Type:application/json,那么API将无误响应,并使API对开发人员更加友好


希望这能有所帮助。

因为PHP不接受JSON
'application/JSON'
一种方法是从angular更新头和参数,以便api可以直接使用数据

首先,参数化数据:

data: $.param({ "foo": $scope.fooValue })
然后将以下内容添加到您的
$http

 headers: {
     'Content-Type' : 'application/x-www-form-urlencoded; charset=UTF-8'
 }, 
如果您的所有请求都将发送到PHP,则可以在配置中全局设置参数,如下所示:


我在服务器端完成这项工作,在init文件的开头,它就像一个符咒,您不必在angular或现有php代码中执行任何操作:

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

角Js演示代码:-

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

?>

由于角度行为,PHP服务器上没有用于正常post行为的直接方法,因此您必须在json对象中对其进行管理。

这是最佳解决方案(IMO),因为它不需要jQuery和json解码:

资料来源: 以及:

总结:

//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"];
?>

这是一个老问题,但值得一提的是,在Angular 1.4中添加了$httpParamSerializer,并且在使用$http.post时,如果我们使用$httpParamSerializer(params)传递参数,那么一切都像常规post请求一样工作,服务器端不需要JSON反序列化


在使用Angular和PHP时,我花了几个小时才明白这一点。 Post数据未在$\u Post中发送到PHP

在PHP代码中,执行以下操作。 -创建变量$angular\u post\u params -然后执行以下操作
$angular\u http\u params=(数组)json\u解码(trim(文件获取内容)()php://input“);

现在,您可以像从$\u POST一样访问参数

$angular\u http\u参数[“键”]

如果你想知道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");
        });
    });

您是否查看了开发人员工具的网络选项卡?在
$http
中传递了什么值?在网络选项卡的
表单数据
下显示
{“电子邮件”:fsdg@sdf.com“,“密码”:“1234”}
@Ronnie看起来像JSON。请尝试
print\r($\u POST);
然后尝试
JSON\u decode()
在正确的索引上
echo'test';
工作正常。我当然是指正确的文件注意.success和.error已被弃用,并替换为.then(),这不是不尊重您的知识,而是使用
文件获取内容(“php://input")
似乎有点像黑客,不是吗?我从来没有听说过。需要做什么才能像
$\u POST['email']一样引用它
@Ronnie这不是黑客行为。这实际上取决于您想如何设置web服务。如果您想发送和检索JSON,您需要使用原始输入,因为
$\u POST
将不会被填充。@lepe我不清楚链接的问题/答案与我的答案之间的关系。没有讨论需要序列化javas这里是script对象。@lascort这两种解决方案实际上没有太大区别。在我的解决方案中,我不是将数据填充到$\u POST中,而是更喜欢用户定义的变量。一般来说,这对我来说更有意义,因为在处理JSON序列化数据时,您可能使用对象或数字索引数组。我不建议将数字索引数组添加到$\u POST,因为这是一种非典型用法。我通常也会避免将数据放入任何用于输入数据的超全局数组。@ItsmeJulian没有绝对正确的答案。这可能真的取决于应用程序的架构。如果您的应用程序正在与REST进行交互使用/交付JSON的服务,然后
    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");
        });
    });