Angular HTTP发布到PHP并且未定义

Ron*_*nie 106 javascript php angularjs

我有一个带标签的表格 ng-submit="login()

该函数在javascript中被称为fine.

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');
        });
    }
}
Run Code Online (Sandbox Code Playgroud)

我从PHP文件中得到200 OK响应,但是,返回的数据是这样email并且password未定义.这是我的所有PHP

<?php
$email = $_POST['email'];
$pass  = $_POST['password'];
echo $email;
?>
Run Code Online (Sandbox Code Playgroud)

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

编辑

我想指出,因为这似乎是一个受欢迎的问题(但它已经过时了),.success并且.error已经被弃用了,你应该使用.then@James Gentes在提交中指出的

Mik*_*ant 223

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;
Run Code Online (Sandbox Code Playgroud)

或者,如果您在很大程度上依赖于$_POST功能,则可以形成类似的查询字符串email=someemail@email.com&password=somepassword并将其作为数据发送.确保此查询字符串是URL编码的.如果手动构建(而不是使用类似的东西jQuery.serialize()),Javascript encodeURIComponent()应该为你做的伎俩.

  • 不是不尊重你的知识,而是使用`file_get_contents("php:// input");`看起来有点像黑客,不是吗?我从来没有听说过这个.需要发生什么,所以我可以像`$ _POST ['email'];`那样引用它 (7认同)
  • @Ronnie这不是一个黑客.这实际上取决于您希望如何设置Web服务.如果要发送和检索JSON,则需要使用原始输入,因为不会填充"$ _POST". (6认同)
  • @lascort确实没有太大的差别.在我的解决方案中,我没有将数据填充到$ _POST中,而是更喜欢用户定义的变量.总的来说,这对我来说更有意义,因为在使用JSON序列化数据时,您可能正在使用wth对象或数字索引数组.我不建议在$ _POST中添加数字索引数组,因为这将是非典型用途.我通常也不愿意将数据放入任何用于输入数据的超全局中. (2认同)

val*_*arv 40

我在服务器端这样做,在我的init文件的开头,就像一个魅力,你不需要在角度或现有的PHP代码中做任何事情:

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

  • 如果$ _POST为空,你应该转换你的结果:`$ _POST =(array)json_decode(file_get_contents('php:// input'),true)`. (3认同)

Tim*_*rom 14

在我正在开发的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));
}
Run Code Online (Sandbox Code Playgroud)

这允许我在需要时简单地将json数据引用为$ _POST ["var"].效果很好.

这样一来,如果经过身份验证的用户连接了一个库,这样的jQuery发送的帖子数据默认为Content-Type:application/x-www-form-urlencoded或Content-Type:application/json,那么API将会毫无错误地响应并且会使API更适合开发人员.

希望这可以帮助.


Mal*_*kus 11

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

首先,参数化您的数据:

data: $.param({ "foo": $scope.fooValue })
Run Code Online (Sandbox Code Playgroud)

然后,将以下内容添加到您的$http

 headers: {
     'Content-Type' : 'application/x-www-form-urlencoded; charset=UTF-8'
 }, 
Run Code Online (Sandbox Code Playgroud)

如果您的所有请求都转到PHP,则可以在配置中将参数设置为全局,如下所示:

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


Raj*_*iya 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);
        });

        }]);
Run Code Online (Sandbox Code Playgroud)

服务器端代码: -

<?php


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

?>
Run Code Online (Sandbox Code Playgroud)

由于角度行为,在PHP服务器上没有直接的方法用于正常的帖子行为,所以你必须在json对象中管理它.


bah*_*mzy 6

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


lep*_*epe 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';
});
Run Code Online (Sandbox Code Playgroud)

例:

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

PHP代码:

<?php
    $id = $_POST["id"];
?>
Run Code Online (Sandbox Code Playgroud)


Sep*_*Sep 5

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

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