Contents
  1. 1. AngularJS使用$http请求传递数据
    1. 1.1. 用法
    2. 1.2. 全部http请求
    3. 1.3. formData问题

AngularJS使用$http请求传递数据

$http服务用于与后端进行数据交互/获取数据然后在UI渲染等. AngularJS核心服务 $http服务, 可认为相当于JQuery中的Ajax.

用法

V1.5版本以下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
$http.get("url").success(function (res){
//do sth... for success response
}).error(function (res){
//do sth... for fail response
});
//Or
var config = {
url: "url",
headers: {...},
data: "data"
};
$http.post(config).success(function s(){
//...
}).error(function (f){
//...
});

V1.5版本以上写法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
//一般写法:
//[类似于JQuery中的Ajax写法]
$http({
method: 'GET',
url: 'http://domain.com/path'
}).then(function successCallBack(){
//请求成功执行的方法
}, function failCallBack(){
//请求失败执行的方法
} );
//或
//将请求方式、API、传递的DATA、以及一些请求设置封装到req对象中.
var req = {
method: 'POST',
url: 'http://example.com',
headers: {
'Content-Type': undefined
},
data: { test: 'test' }
}
//V1.5 的.then 方法
$http(req).then(function(){...}, function(){...});

全部http请求

1
2
3
4
5
6
7
$http.get
$http.head
$http.post
$http.put
$http.delete
$http.jsonp
$http.patch

参考:

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

formData问题

默认情况下使用post请求向后端传递数据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<script>
var app = angular.module("httpDemo", []);
app.controller("httpDemoController", function($scope, $http) {
$scope.data = {
name: "lomoa",
age: 22,
sex: "male"
};
$http({
method: "POST",
data: $scope.data,
url: "./data.json"
}).then(function successFn(response) {
$scope.names = response.data.sites;
}, function failFn(response) {
//do nothing here if fail
});
});
</script>

Charles抓包查看Http请求传递的数据格式为JSON Text,如下图所示:


>

思考🤔:

这样以来的话,如果后端接口未改变,那么前端使用AngularJS的$http服务请求API传递数据就会出现问题,导致后端接受不到JSON数据.

例如, 后端PHP开发的Restful API, 部分代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
if (isset($_POST['login'])) {
$login = $_POST['login'];
$email = $_POST['email'];
$password = $_POST['password'];
$addr = getEnv("REMOTE_ADDR");
$result = mysqli_query($conn, "SELECT * FROM users WHERE email = '" . $email. "' and password = '" . md5($password) . "'");
if ($row = mysqli_fetch_assoc($result)) {
$u = new \generateUUID\Uuid($addr);
$uuid = $u -> uuid();
//.....
//....
}
}
// 这样的话,$_POST就接受不到来自前端传过来的非formData形式的数据

此时在AngularJS应用中,需要将传输的JSON数据格式转为Formdata格式(否则,就修改后端接口? 呵呵🙄)

针对此问题,有2种解决方案(个人已知!)

方案1:

使用jQuery的$.param序列化函数.

对$http请求中的 $scope.data 直接使用 $.param 函数序列化data对象即可.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
app.controller('httpDemoController', function($scope, $http) {
$scope.data = {
name: 'lomo',
age: 25,
sex: 'male',
height: '1980'
},
$http({
method: 'POST',
data: $.param($scope.data),
headers : { 'Content-Type': 'application/x-www-form-urlencoded' },
url: './data.json'
}).then(function successCallback(response) {
$scope.names = response.data.sites;
}, function errorCallback(response) {
// 请求失败执行代码
});
});

此种方法需要引入jQuery类库,依据情况决定是否有必要为了使用这个函数而引入该库(通常不会!), 如果项目其它多处也需要使用jQuery的其它功能,那么就可以,方便使用。

此外,还需要在请求中设置headers, headers : { 'Content-Type': 'application/x-www-form-urlencoded' } 这样,嗯。就是酱紫😯。

方案2:

手动序列化data对象.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
<script>
var app = angular.module("httpDemo", []);
app.service('params', function() {
this.jsonToString = function(obj) {
var query = '',
name, value, fullSubName, subName, subValue, innerObj, i;
for (name in obj) {
value = obj[name];
if (value instanceof Array) {
for (i = 0; i < value.length; ++i) {
subValue = value[i];
fullSubName = name + '[' + i + ']';
innerObj = {};
innerObj[fullSubName] = subValue;
query += param(innerObj) + '&';
}
} else if (value instanceof Object) {
for (subName in value) {
subValue = value[subName];
fullSubName = name + '[' + subName + ']';
innerObj = {};
innerObj[fullSubName] = subValue;
query += param(innerObj) + '&';
}
} else if (value !== undefined && value !== null)
query += encodeURIComponent(name) + '=' + encodeURIComponent(value) + '&';
}
return query.length ? query.substr(0, query.length - 1) : query;
}
});
app.controller("httpDemoController", function($scope, $http, params) {
$scope.data = {
name: "lomoa",
age: 22,
sex: "male"
};
$http({
method: "POST",
data: params.jsonToString($scope.data),
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
url: "./data.json"
}).then(function successFn(response) {
$scope.names = response.data.sites;
}, function failFn(response) {
//do nothing here if fail
});
});
</script>

headers必须要设置,无论是方案1还是方案2 !!!

抓包查看请求传递的参数:


>

方案2 完整Demo

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<meta property="og:site_name" content="Demo" />
<meta property="og:type" content="demo">
<meta property="og:author" content="admin@lomo.space">
<meta property="og:publisher" content="Wechat@Lomo" />
<meta property="og:masterEmail" content="lomo@lomo.space" />
<title>HTTP请求传递参数问题</title>
<script src="./lib/angular-1.6.3.min.js"></script>
</head>
<body>
<div class="demo" ng-app="httpDemo" ng-controller="httpDemoController">
<ul>
<li ng-repeat="x in names">
{{x.Name + ', ' + x.Country}}
</li>
</ul>
</div>
<script>
var app = angular.module("httpDemo", []);
app.service('params', function() {
this.jsonToString = function(obj) {
var query = '',
name, value, fullSubName, subName, subValue, innerObj, i;
for (name in obj) {
value = obj[name];
if (value instanceof Array) {
for (i = 0; i < value.length; ++i) {
subValue = value[i];
fullSubName = name + '[' + i + ']';
innerObj = {};
innerObj[fullSubName] = subValue;
query += param(innerObj) + '&';
}
} else if (value instanceof Object) {
for (subName in value) {
subValue = value[subName];
fullSubName = name + '[' + subName + ']';
innerObj = {};
innerObj[fullSubName] = subValue;
query += param(innerObj) + '&';
}
} else if (value !== undefined && value !== null)
query += encodeURIComponent(name) + '=' + encodeURIComponent(value) + '&';
}
return query.length ? query.substr(0, query.length - 1) : query;
}
});
app.controller("httpDemoController", function($scope, $http, params) {
$scope.data = {
name: "lomoa",
age: 22,
sex: "male"
};
$http({
method: "POST",
data: params.jsonToString($scope.data),
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
url: "./data.json"
}).then(function successFn(response) {
$scope.names = response.data.sites;
}, function failFn(response) {
//do nothing here if fail
});
});
</script>
</body>
</html>


Creative Commons License
本文由Lomo创作和发表,采用Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License进行许可.
转载请注明作者及出处,本文作者为Lomo,本文标题为angular request.
Contents
  1. 1. AngularJS使用$http请求传递数据
    1. 1.1. 用法
    2. 1.2. 全部http请求
    3. 1.3. formData问题