【问题标题】:$http not displaying response in angularjs app$http 未在 angularjs 应用程序中显示响应
【发布时间】:2014-08-07 16:10:58
【问题描述】:

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

  1. php 没有收到我发送给它的数据
  2. angularjs 没有在页面上显示 php 响应。

我是根据 tut 构建的: 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"}]';
}

感谢您对此事的帮助

【问题讨论】:

  • 您的浏览器开发工具上的网络活动是什么样的?它会转到正确的网址吗?
  • 你的意思是php文件路径吗? Firebug 显示一个成功的帖子,其中包含来自相关 php 文件的响应消息。 Angular 只是未能向其传递数据值并从中捕获响应消息。
  • 你的代码有两个问题:一个是你的,一个是angular+php的。看我的回答

标签: javascript php ajax angularjs


【解决方案1】:

这里有两个问题:

首先: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 类型的,因此毫无疑问 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. 有一种方法可以为每个请求安装数据预处理。但是它对我不起作用。相反,我向$http.postdata 参数传递了一个由以下函数转换的值(您可以使用它或必须编写一个符合您需要的代码):

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

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

【讨论】:

  • 非常感谢您的帮助,我使用了您的大部分代码,并且能够让 php 查看我发送的数据并通过标头响应返回我的值,但 angular 仅警告对象回复。 $s 参数是什么?我现在把它注释掉了(未定义)
  • 我应该注意我已经尝试过 response.data[0].message, response[0].message 返回 undefined 和 response.message 返回“$digest already in progress”响应本身返回简单的对象
  • 我将 ajax 函数中的$s 设为$scope$http$q 实际上就是这些服务。请记住,这不是控制器,而是我在项目中使用的内部函数。
  • 也许这些对象是未定义的,因为 Angular 不将它们视为对象。确保您在 php 中发送 application/json 内容类型并且可以正常工作。
猜你喜欢
  • 1970-01-01
  • 2014-03-05
  • 1970-01-01
  • 1970-01-01
  • 2016-07-14
  • 2020-01-16
  • 1970-01-01
  • 2022-07-19
  • 1970-01-01
相关资源
最近更新 更多