我正在开发一个angularjs应用程序和我试图设置的$ http连接到php文件,标题显示我从php回应的响应。我的问题是:
我是基于一个啧啧建立的: 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"}]';
}
感谢此事的帮助
答案 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?的预处理强>:
这就是我设置模块以预处理每个请求的方式,使其处于与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';
}]);
有一种方法可以为每个请求安装数据的预处理。但它对我不起作用。相反,我将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
最后,我使用抽象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 || {}
}
);
}
我稍后会使用成功和错误回调进行自定义。