$http服务
1、$http 是 AngularJS 中的一个核心服务,用于读取远程服务器的数据。
2、angular内置的$http服务简单的封装了浏览器原生的XMLHttpRequest对象,可以直接同外部进行通信。
3、$http服务只能接受一个参数,且该参数是一个对象,这个对象主要包含一些http请求的配置内容。如下:
var req = {
method: 'POST',
url: 'http://xxx.com',
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
data: { test: 'test' }
}
//以下写法在angular1.5+已废弃
$http(req).success(function(data,header,config,status){
//响应成功
}).error(function(data,header,config,status){
//处理响应失败
});
//以下写法在angular1.5+支持
$http(req).then(
function successCallback(res){
//响应成功
},function errorCallback(res){
//处理响应失败
}
)
可以看到$http()方法返回的是一个promise对象,angular1.5+版本只支持响应返回时用then回调。但是用then回调会得到一个特殊的参数,代表了相应对象的成功或失败信息,还可以接受两个可选的函数作为参数。如:
$http(req).then(function(resp){
//resp是一个响应对象
},function(resp){
//带有错误信息的resp
});
then()方法回调和success(),error()回调的区别是,then()会接收到完整的对象,而success()和error()会对响应进行解构。
then()函数接收的response(响应对象)包含5个属性:
1、data(字符串或对象):响应体,就是后台返回的数据
2、status:相应http的状态码,如200
3、headers(函数):头信息的getter函数,可以接受一个参数,用来获取对应名字的值
4、config(对象):生成原始请求的完整设置对象
5、statusText:相应的http状态文本,如"ok"
6、xhrStatus: “complete”
常见$http的GET和POST传参问题:
一、GET,get比较简单,用惯ajax的同学都知道get一般通过url中拼接字符串进行请求,而在angular中get请求地址和参数分开,如下:
var req = {
method: 'GET',
url: 'http://xxx.com',
header: {
'Content-Type': 'application/x-www-form-urlencoded'
},
params: {
'id': id,
'code': xcode
}
}
$http(req).then(function successCallback(res){
//success
},function errorCallback(res){
//faild
})
二、POST
1、不能直接使用params,例如:
var req = {
method: 'POST',
url: 'http://xxx.com',
header: {
'Content-Type': 'application/x-www-form-urlencoded'
},
params: {
'name': 'jack',
'id': '12'
}
}
$http(req).then(function successCallback(res){
//success
},function errorCallback(res){
//faild
})
当你这样写的时候它会把id写到url后面就会出现:
http://xxx.com?name=jack&id=12
会在url后面添加"?name=jack"等等,因为params这个参数是用在GET请求中的,而POST/PUT/PATCH就需要使用data来传递;
扫描二维码关注公众号,回复: 8552901 查看本文章
2、直接使用data
var req = {
method: 'POST',
url: 'http://xxx.com',
data: {
'name': 'jack',
'id': '12'
}
}
$http(req).then(function successCallback(res){
//success
},function errorCallback(res){
//faild
})
这样的话传递的,是存在于Request Payload中,后端无法获取到参数(可在network中查看)
这时发现Content-Type:application/json;charset=UTF-8,而POST表单请求提交时,使用的Content-Type是application/x-www-form-urlencoded,所以需要把Content-Type修改下!
3、修改一下Content-Type
var req = {
method: 'POST',
url: 'http://xxx.com',
header: {
'Content-Type': 'application/x-www-form-urlencoded'
},
data: {
'name': 'jack',
'id': '12'
}
}
$http(req)...//同上
这个时候数据仍然没有传递到后台去,虽然数据是放到了Form Data中但是发现是以对象的形式存在,所以需要进行序列化!
4、对参数进行序列化,通过属性transformRequest完成:
var req = {
method: 'POST',
url: 'http://xxx.com',
header: {
'Content-Type': 'application/x-www-form-urlencoded'
},
transformRequest: function(obj) {
var str = [];
for (var s in obj) {
str.push(encodeURIComponent(s) + "=" + encodeURIComponent(obj[s]));
}
return str.join("&");
}
data: {
'name': 'jack',
'id': '12'
}
}
$http(req)...//同上
自此完成post传参。
$http封装
1、$http的普通使用
$http({
method: "GET",
url: url,
headers: {
},
timeout: 10000
}).then(successCallBack,errorCallBack);
这样的使用方式的问题在哪?
第一:如果一个项目的接口有100个,那这样的引用方式会引起大量的冗余代码。
第二:Api不够简洁,无法提供一个忽视底层实现的方式进行服务请求。比如,上传文件的时候要对headers进行额外的设置等。
第三:最重要的是,毫无技术积累(逼格不够高),下次同样的项目,你的代码还是无法复用,还是需要一遍遍的写$http。
so,我们要对 $http 进行封装,形成简洁易用、结构清晰的数据请求 Api。
2、angular服务封装的目标和实现思路。
目标:封装成向顶层提供get、post两种方式的Api,Api的参数配置只和url、data相关。形成类似于 RequestService.get(url,data).then 这样的Api。
封装思路:由于angular的$http本身就是基于Promise的,所以本身不用引入第三方promise库。只需要把相同的部分提取出来即可。当然,angular在这方面还提供了全局的拦截器服务。
3、封装
第一步、定义一个基于服务module模块。
//BaseService.module.js
(function(){
"use strict";
angular.module('BaseService',[]);
})();
第二步、拦截器实现
//BaseService.intercepter.js
(function(){
"use strict";
angular.module('BaseService')
.factory('requestInterceptor', function ($rootScope, $log){
return{
request:function(config){
return config;
},
requestError:function(config){
return config;
},
response:function(res){
//res返回不正常的处理
return res;
},
responseError:function(res){
//res返回错误处理
}
}
}).config(function($httpProvider){
$httpProvider.interceptors.push('requestInterceptor');
})
})();
第三步、公共提取
//BaseService.comm.js
(function(){
'use strict';
angular.module('BaseService')
.config(function(){
$httpProvider.defaults.useXDomain = true; // 发送CORS
$httpProvider.defaults.withCredentials = false; // 请求携带Cookies
delete $httpProvider.defaults.headers.common['X-Requested-With'];
})
.provider("RequestService",function(){
return {
$get: function(){
return {
get:function(url,data,processor){
//coding
},
post:function(url,data){
//coding
},
request: request
}
}
}
})
})()
ps:以上是对angular中$http服务的使用笔记。