108

我有一个带有标签的表格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 响应,但是,返回的数据说明了这一点email并且password是未定义的。这是我所有的php

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

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

编辑

我想指出,因为这似乎是一个流行的问题(但它已经过时),.success并且.error已被弃用,您应该使用.then@James Gentes 在评论中指出的

4

9 回答 9

229

angularjs.post()默认 Content-type 标头为application/json. 您将覆盖它以传递表单编码的数据,但是您没有更改您的data值以传递适当的查询字符串,因此 PHP 没有$_POST按您的预期填充。

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

这可以在 PHP 中像这样实现:

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

或者,如果您严重依赖$_POST功能,您可以形成一个查询字符串email=someemail@email.com&password=somepassword,并将其作为数据发送。确保此查询字符串是 URL 编码的。如果手动构建(而不是使用类似的东西jQuery.serialize()),JavascriptencodeURIComponent()应该为您解决问题。

于 2013-03-18T19:54:40.593 回答
41

我在服务器端执行此操作,在我的 init 文件的开头,它就像一个魅力,你不必在角度或现有的 php 代码中做任何事情:

if ($_SERVER['REQUEST_METHOD'] == 'POST' && empty($_POST))
    $_POST = json_decode(file_get_contents('php://input'), true);
于 2014-06-10T12:25:20.510 回答
15

在我正在开发的 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"]。效果很好。

这样,如果经过身份验证的用户连接到诸如 jQuery 之类的库,该库使用默认的 Content-Type: application/x-www-form-urlencoded 或 Content-Type: application/json 发送帖子数据,API 将无错误地响应,并将使 API 对开发人员更加友好。

希望这可以帮助。

于 2014-05-22T14:56:15.640 回答
11

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

首先,参数化您的数据:

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

然后,将以下内容添加到您的$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';
});
于 2014-05-22T19:01:59.840 回答
8

Angular 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 服务器上的正常发布行为没有直接的方法,因此您必须在 json 对象中对其进行管理。

于 2014-06-27T06:46:54.600 回答
6

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

于 2014-03-18T00:02:42.790 回答
6

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

来源: https ://wordpress.stackexchange.com/a/179373 和: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"];
?>
于 2015-03-11T14:31:05.520 回答
5

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

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

于 2015-06-17T02:34:42.157 回答
1

在使用 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");
        });
    });
于 2016-07-14T08:04:46.267 回答