$ http不会在angularjs app中显示响应

时间:2014-08-07 16:10:58

标签: javascript php ajax angularjs

我正在开发一个angularjs应用程序和我试图设置的$ http连接到php文件,标题显示我从php回应的响应。我的问题是:

  1. php没有收到我发送给它的数据
  2. angularjs没有在页面上显示php响应。
  3. 我是基于一个啧啧建立的: http://www.bennadel.com/blog/2612-using-the-http-service-in-angularjs-to-make-ajax-requests.htm

    这是我的角度控制器

    app.controller('LoginCtrl', ['$scope', 'userServices', function($scope, userServices) {
        $scope.users = userServices.loginUser();
    }]);
    

    这是我的角色服务

    app.factory('userServices', ['$http', function($http, $q) {
    
        // return public api
        return ({
            loginUser: loginUser
        });
    
        /*
         * attempt to login user
         * returns user profile info if succeed or false if no match found
         */
        function loginUser() {
            var request = $http({
                method: "post",
                url: "../data/user.php",
                params: {
                    action: "login"
                },
                data: {
                    userName: "me",
                    userPass: "pass"
                }
            });
            return ( request.then(handleSuccess, handleError));
        }
        /*
         * transform error response, unwrapping application data
         */
        function handleError(response) {
    
            // response should be returned in a normalized format
            // when errors are given by the server we send our formated error
            if(!angular.isObject(response.data) || !response.data.message) {
                return( $q.reject("An unknown error occured"));
            }
            // use expected error message
            return($q.reject(response.data.message));
        }
    
        // for success we unwrap the application data from API response payload
        function handleSuccess(response) {
            return(response.data.message);
        }
    

    最后这是我的php文件

    if(isset($_POST['userName'])) { // 'userName' is not set
        echo '[{"message": "userName is '.$_POST['userName'].'"}]';
    }  else {
        // php current returns this message in the header response
        // angular is not seeing this message
        echo '[{"message": "userName not set"}]';
    }
    

    感谢此事的帮助

1 个答案:

答案 0 :(得分:0)

这里有两个问题:

首先:PHP无法处理application/json Content-Type作为输入。

我的代码中遇到了同样的问题。您必须切换到application/x-www-form-urlencoded类型 - 不知道为什么json是http请求的默认角度序列化方式,但是PHP - 这是用于网页的最多服务器端技术 - 不处理该类型,并为$_GET$_POST提供空数据。

因此,您必须预先处理您的请求(我们稍后会解决此问题)。

第二次:对于您返回的数据。你在回应:

'[{"message": "userName not set"}]'

这是一个数组。所以你必须以下列方式访问它:

response.data[0].message

而不是

response.data.message

并且你必须确保响应是json-typed 才能回显,所以毫无疑问,angular会将其视为json:

//don't echo anything before this
header('Content-Type: application/json');
//... more code here
if(isset($_POST['userName'])) { // 'userName' is not set
    echo '[{"message": "userName is '.$_POST['userName'].'"}]';
}  else {
    // php current returns this message in the header response
    // angular is not seeing this message
    echo '[{"message": "userName not set"}]';
}

现在让我们收回我们以后留下的内容:我们将如何将数据从Angular发送到PHP?的预处理

  1. 这就是我设置模块以预处理每个请求的方式,使其处于与PHP兼容的格式。

    var index = angular.module("Application", ['ngRoute', 'ngResource'], ['$httpProvider', function($httpProvider){
        $httpProvider.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded;charset=utf-8';
    }]);
    
  2. 有一种方法可以为每个请求安装数据的预处理。但它对我不起作用。相反,我将data参数传递给$http.post一个由以下函数转换的值(您可以使用它或必须编写符合您需要的值):

    var phpserializer = {
        __encode: function(name, value) {
            return window.encodeURIComponent(name) + '=' + window.encodeURIComponent(value);
        },
        __isPrimitive: function(value) {
            return value instanceof Boolean || value instanceof String || value instanceof Number || !(value instanceof Object);
        },
        __isDate: function(value) {
            return value instanceof Date;
        },
        __indexed: function(prefix, property) {
            return prefix ? (prefix + '[' + property + ']') : property;
        },
        __serializeDate: function(value) {
            return {
                'day': value.getDay(),
                'month': value.getMonth(),
                'year': value.getFullYear(),
                'hours': value.getHours(),
                'minutes': value.getMinutes(),
                'seconds': value.getSeconds(),
                'milliseconds': value.getMilliseconds(),
                'timezone': value.getTimezoneOffset()
            }
        },
        __params: function(data, prefix, query) {
            angular.forEach(data, function (value, index) {
                var fullIndex = this.__indexed(prefix, index);
                if (this.__isPrimitive(value)) {
                    //objetos primitivos, valores primitivos (exc. undefined)
                    if (typeof value !== "undefined") query.push(this.__encode(fullIndex, value));
                } else if (this.__isDate(value)) {
                    //objetos fecha: metemos los componentes
                    //que son relevantes a la fecha
                    this.__params(this.__serializeDate(value), fullIndex, query);
                } else {
                    //datos tipo objeto o array, ambos iterables en angular
                    this.__params(value, fullIndex, query);
                }
            }, this);
        },
        params: function(param) {
            var q = [];
            if (this.__isPrimitive(param) || this.__isDate(param) || param instanceof Array) {
                param = {'value': param};
            }
            this.__params(param, '', q);
            return q.join('&');
        }
    };
    

    您必须调整此代码以满足您的需求(例如,我使用自定义的日期序列化,这对您来说可能不太有用)。此功能会将{a: {b: 1, c: 2}, d: 3}转换为?a[b]=1&a[c]=2&d=3

  3. 最后,我使用抽象ober $http来执行POST请求:

    function ajax_post($http, data, $s, $q, target, params) {
        cancelCurrent($s);
        $s.canceller = $q.defer();
        return $http.post(
            target,
            phpserializer.params(data),
            {
                headers: {
                    'Content-Type': 'application/x-www-form-urlencoded;charset=utf-8'
                },
                timeout: $s.canceller.promise,
                params: params || {}
            }
        );
    }
    

    我稍后会使用成功和错误回调进行自定义。